复习 贪心算法 没有套路只有思路,从局部最优解找到全局最优解
455 分发饼干 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int findContentChildren (int [] g, int [] s) { Arrays.sort(g); Arrays.sort(s); int indexC = 0 ; int indexG = 0 ; int count = 0 ; while (indexC < s.length){ if (s[indexC] >= g[indexG]){ count++; indexC++; indexG++; } else { indexC++; } if (count == g.length) return count; } return count; } }
376 摆动序列 在更新preDiff的时候需要注意时机,只有在更新count的时候才更新prediff 即在摆动时更新,就不会在单调区间时出问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int wiggleMaxLength (int [] nums) { if (nums.length < 1 ) return 0 ; int count = 1 ; int index = 1 ; int curDiff = 0 ; int preDiff = 0 ; for (index = 1 ; index < nums.length; index++){ curDiff = nums[index] - nums[index - 1 ]; if ((preDiff <= 0 && curDiff > 0 ) || (preDiff >= 0 && curDiff < 0 )){ count++; preDiff = curDiff; } } return count; } }
53 最大子序和 具体逻辑,就是不停累加数组里面的数,遇到负数,就清空sum,即舍弃前面所有的总和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public int maxSubArray (int [] nums) { int sum = 0 ; int maxSum = Integer.MIN_VALUE; for (int i = 0 ; i < nums.length; i++){ sum += nums[i]; maxSum = Math.max(maxSum, sum); if (sum < 0 ) sum = 0 ; } return maxSum; } }
122 买卖股票的最佳时机II 此题即将所有两个值的区间为正值的数加在一起,负值舍弃,在贪心算法中,每一天如果买进,第二天卖出则所有正值就是最大值 最终利润可以分解, 所以可以用贪心算出每一天的收益
1 2 3 4 5 6 7 8 9 10 11 12 class Solution { public int maxProfit (int [] prices) { if (prices.length < 1 ) return 0 ; int sum = 0 ; for (int i = 1 ; i < prices.length; i++){ int curDiff = prices[i] - prices[i - 1 ]; if (curDiff > 0 ) sum += curDiff; } return sum; } }
55 跳跃游戏 这道题本质是累加nums[i]之后的数字,找到是不是>=数组长度
此题的难点是在于for loop 之中的判断条件是累加的,是变化的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public boolean canJump (int [] nums) { if (nums.length == 1 ) return true ; int coverage = 0 ; for (int i = 0 ; i <= coverage; i++){ coverage = Math.max(coverage, i + nums[i]); if (coverage >= nums.length - 1 ){ return true ; } } return false ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public boolean canJump (int [] nums) { if (nums == null || nums.length <= 1 ) return true ; int maxDistance = 0 ; for (int i = 0 ; i < nums.length; i++){ maxDistance = Math.max(maxDistance, i+ nums[i]); if (maxDistance >= nums.length - 1 ) return true ; if (maxDistance == i && nums[i] == 0 ) return false ; } return true ; } }
45 跳跃游戏II 思路: 解题要从覆盖范围出发,不管怎么跳,覆盖范围一定可以跳到,最小步数增加覆盖范围,一旦覆盖了终点就是最小步数 利用current distance 记录走的步数,如果i == curdistance, 就相当于走到了现在的max的最终,需要count++;
也就是如果i走到超过当前可覆盖的最大范围,则count就需要加一了,这之后覆盖记录的这一count之中最大范围值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution { public int jump (int [] nums) { if (nums.length <= 1 || nums == null ) return 0 ; int count = 0 ; int curDistance = 0 ; int maxDistance = 0 ; for (int i = 0 ; i < nums.length; i++){ maxDistance = Math.max(maxDistance, i + nums[i]); if (maxDistance >= nums.length - 1 ){ count++; break ; } if (i == curDistance){ curDistance = maxDistance; count++; } } return count++; } }
解法需要温习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution { public int jump (int [] nums) { int result = 0 ; int end = 0 ; int temp = 0 ; for (int i = 0 ; i <= end && end < nums.length - 1 ; i++){ temp = Math.max(temp, i + nums[i]); if (i == end) { end = temp; result++; } } return result; } }