738.单调递增的数字 ,968.监控二叉树 +贪心总结

738.单调递增的数字 

示例:如将322变成成单调递增的最大数字即299,如3442变成3399

首先要将n转换成字符数组,

其次遍历数组进行两次判断:

第一次是遍历数字时求当前最大的数字max。然后只在max

第二次要判断是否有arr[i]>arr[i+1],如果是那么要将arr[idx]减1,同时将之后的位数都替换成'9'

代码实现

class Solution {
    public int monotoneIncreasingDigits(int n) {
        //把n转换成字符串
       char[] arr = (n + "").toCharArray();
       int max=-1,idx=-1;
       //从前往后遍历数组
       for(int i=0;iarr[i+1]){
               arr[idx]-=1;
               for(int j=idx+1;j

968.监控二叉树 (一刷跳过)

贪心总结

贪心简单题

分发饼干:对两个数组进行排序,遍历两个数组,每次如果当前饼干不能满足当前小孩胃口,那么就试试下一块饼干。

k次取反后最大化的数组和:由于数组中包含负数,我们优先对负数取反,全部负数取反后如果k>0就对最小正数取反,因为题目给出的元素范围是[-100,100]所以我们可以把数字都映射到一个number数组上

柠檬水找零:思路比较简单,因为顾客只会付给我5块,10块,20块,我们可以记录手头上有几张5块,几张10块,几张20块

贪心中等题

摆动序列:数组元素间的差值是正负交替的,说明是摆动序列。这道题我们首先定义preSum和curSum,前者为上上个元素和上个元素的差值,后者为上个元素和当前元素的差值,需要找到峰值也就是需要满足if (preDiff<=0&&curDiff>0)||(preDiff>=0&&curDiff<0),满足这个if的时候要更新preSum

738.单调递增的数字:这道题首先要将n转换成字符串,从前往后遍历数组,需要记录截止到遍历的位置时的最大值和最大值下标,方便的是当遇到不是递增的数字时,知道从哪个下标开始将后续字符全部变成字符9

122.买卖股票的最佳时机 II:任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
53.最大子数组和:遍历数组,然后对两两元素做减法,如果减法的结果大于0,那么将这个结果累

加到sum中

134. 加油站:首先如果所有的rest[i]相加起来小于0,那么是永远不可能环绕成功的,我们用curSum来累加rest[i],一旦curSum小于0,哪就要更新起始位置到i+1,然后把curSum重新置为0

两个维度权衡问题

两个维度的问题要一个一个维度考虑,否则容易顾此失彼。

分发糖果:这道题要求相邻两个孩子中评分更高的孩子会获得更多机会,需要两次遍历,第一次从左往右遍历(右孩子如果比左孩子评分高,则右孩子糖果数在左孩子基础上加1),在第一次遍历的基础上再从右往左遍历(如果左孩子评分比右孩子评分高,那么左孩子糖果数取当前糖果数和右孩子糖果数+1二者中的较大者)

根据身高重建队列:首先根据身高降序,身高若相同就按ki升序。排完序后创建一个队列,我们需要按索引大小往队列中插入元素,在这道题中用到的分发que.add(index,value)是向指定下标插入元素value

贪心难题

这里的题目如果没有接触过,其实是很难想到的,甚至接触过,也一时想不出来,所以题目不要做一遍,要多练!

贪心解决区间问题

跳跃游戏:返回是否能够跳跃到数组的最右端,给定数组中每个元素代表能够跳跃的最大长度,有点类似滑动区间,每次在可达区间范围内寻找一个能跳最大距离的元素

跳跃游戏II:返回到达nums[n-1]的最小跳跃次数,这道题和上一道思路基本一致,需要找出在可达区间范围内能跳最大距离的元素,根据end与当前下标i是否相等来判断是否更新最远距离end和count++

用最少数量的箭引爆气球:我们要返回引爆索引气球的箭数量,首先需要根据xstart进行升序排序,如果两个气球没有重复部分count++,如果两个气球有重复部分,那么就需要更新右边气球的xend

435. 无重叠区间:返回 需要移除区间的最小数量,使剩余区间互不重叠 。首先需要根据数组第一位元素升序,例如排完序后:[1,2],[1,3],[2,3],[3,4].如果遇到有区间的情况就需要调整右边界

763.划分字母区间:题目要求我们要划分尽可能多的字段,同一个字母只能出现在一个字段,因此我们首先需要遍历字符串然后标记每个字符(字母)最后一次出现的下标,得到这个标记数组后,我们再次遍历字符串,idx的作用就是在这个范围内有不同的字母,但我们要一直保持是最远距离的字母的下标作为idx

56. 合并区间:这道题今天二刷,首先还是需要按照数组的第一位元素对数组进行升序,我们需要自定义个区间[start,rightmostBound],在遍历给定数组时把intervalsvals[i][0]和rightmostBound比较,如果前者大于后者说明没有重叠,那么将区间直接添加到结果集res中,否则需要何必跟区间,把rightmostBound更新为rightmostBound和intervalsvals[i][1]中的更大者

体会:

在这个过程中,很多贪心问题都需要先对数组进行排序,一般情况下都没什么思路,但是做过后再看一遍会好很多

你可能感兴趣的:(算法,java,数据结构)