贪心算法
分发饼干
题目描述
有两个数组,一个代表小孩,一个代表饼干,第$i$个小孩的值是饥饿度,第$i$个饼干是饱和度,请问,饼干最多能让多少小孩吃饱。
解题思路
小饼干先喂饱小胃口。下面的代码中利用遍历cookie来遍历胃口数组,并没有再使用一个for循环,而是采用自加的方式,这也是常用的技巧。
public static int findContentChildren(int[]cookies, int[]children) {                  Arrays.sort(cookies);         Arrays.sort(children);         int child = 0;         int cookie = 0;                  while (child < children.length && cookie < cookies.length) {             if (children[child] <= cookies[cookie++])                 child++;         }         return child;     }
 
  | 
 
摆动序列
题目描述
给定一个整数序列,返回作为摆动序列的最长子序列的长度。通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
解题思路
局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。
整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。
实际操作上,其实连删除的操作都不用做,因为题目要求的是最长摆动序列的长度,所以只需要统计数组的峰值数量就可以了。
public static int wiggleMaxLength(int[] nums) {         if (nums.length <= 1) {             return nums.length;         }         int result = 1;         int pre = 0;         int cur = 0;         for (int i = 1; i < nums.length; i++) {             cur = nums[i] - nums[i-1];             if (cur > 0 && pre <= 0 || cur < 0 && pre >= 0) {                 result++;                 pre = cur;             }         }         return result;     }
 
  | 
 
最大子序和
题目描述
给定一个整数数组nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
解题思路
局部最优:当前连续和为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素的连续和只会越来越小。
全局最优:选取最大“连续和”。
public static int Maximum_Suborder_Sum(int[] nums) {         if (nums.length == 1) {             return nums[0];         }         int count = 0;         int max = Integer.MIN_VALUE;         for (int i = 0; i < nums.length; i++) {             count += nums[i];                          max = Math.max(max, count);             if (count < 0){                                  count = 0;             }         }         return 0;     }
 
  | 
 
买卖股票的最佳时机II
题目描述
给定一个数组,它的第i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
解题思路
其实只需要收集每天的正利润就可以了,收集正利润的区间,就是股票买卖的区间,而只需要关注最终利润,不需要记录区间。
局部最优:收集每天的正利润,全局最优:求得最大利润。
public static int maxProfit(int[] prices) {
          int max = 0;          int flag = 0;          int cur = 0;         for (int i = 1; i < prices.length; i++) {             cur = prices[i] - prices[i-1];             if (cur > 0) {                 max += cur;                 flag = 1;             }             if (cur < 0 && flag == 1) {                 flag = 0;             }                                   }         return max;     }
 
  |