当前位置:   article > 正文

初步了解贪心算法_nums = intstream.of(nums) .boxed() .sorted((o1,

nums = intstream.of(nums) .boxed() .sorted((o1, o2) -> math.abs(o2) -

 

 

 

  1. class Solution {
  2. public int findContentChildren(int[] g, int[] s) {
  3. Arrays.sort(g);
  4. Arrays.sort(s);
  5. int gLen = g.length;
  6. int sLen = s.length;
  7. int i = 0;
  8. int j = 0;
  9. int count = 0;
  10. while (i < gLen && j < sLen) {
  11. while (j < sLen) {
  12. if (s[j] >= g[i]) {
  13. count++;
  14. break;
  15. }
  16. j++;
  17. }
  18. i++;
  19. j++;
  20. }
  21. return count;
  22. }
  23. }

  1. //这是贪心算法得,我觉得应该就是,这个题目也必须得从第一个开始啊,不可能说后几个个数比加上前面还大,所以是贪心算法得题目吧
  2. class Solution {
  3. public int wiggleMaxLength(int[] nums) {
  4. if (nums.length == 1) return 1;
  5. if (nums.length == 2 && nums[0] != nums[1]) return 2;
  6. //太久没写都忘记了,和前一个对比直接定义就行
  7. int curDiff = 0;
  8. int preDiff = 0;
  9. int count = 0;
  10. for (int i = 1; i < nums.length; i++) {
  11. curDiff = nums[i] - nums[i - 1];
  12. //循环得时候直接忽略掉不想等于0得时候就行
  13. if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
  14. count++;
  15. preDiff = curDiff;
  16. }
  17. }
  18. return count + 1;
  19. }
  20. }

  1. //1.13贪心算法
  2. //明白贪心算法得意义
  3. class Solution {
  4. public int maxSubArray(int[] nums) {
  5. if (nums.length == 1) return nums[0];
  6. int count = 0;
  7. int sum = Integer.MIN_VALUE;
  8. for (int i = 0; i < nums.length; i++) {
  9. count += nums[i];
  10. sum = Math.max(sum , count);
  11. //那么前面那一堆肯定是最近得那个让前面总和小于0(题目是连续部分,所以这样,理解理解)
  12. //而且这样还把我第一次想是负数就下一个开始得思想也包含了
  13. if (count <= 0) count = 0;
  14. }
  15. return sum;
  16. }
  17. }
  18. // 贪心贪的是哪里呢?
  19. // 如果 -2 1 在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方!
  20. // 局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
  21. // 全局最优:选取最大“连续和”
  22. // 局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
  23. // 从代码角度上来讲:遍历nums,从头开始用count累积,如果count一旦加上nums[i]变为负数,那么就应该从nums[i+1]开始从0累积count了,因为已经变为负数的count,只会拖累总和。

 

  1. // 贪心思路
  2. //自己考虑得那中大范围跨度,比两个小范围跨度大是错误得
  3. class Solution {
  4. public int maxProfit(int[] prices) {
  5. int result = 0;
  6. for (int i = 1; i < prices.length; i++) {
  7. result += Math.max(prices[i] - prices[i - 1], 0);
  8. }
  9. return result;
  10. }
  11. }

 

  1. class Solution {
  2. public boolean canJump(int[] nums) {
  3. if (nums.length == 1) {
  4. return true;
  5. }
  6. //覆盖范围, 初始覆盖范围应该是0,因为下面的迭代是从下标0开始的
  7. int coverRange = 0;
  8. //在覆盖范围内更新最大的覆盖范围
  9. for (int i = 0; i <= coverRange; i++) {
  10. coverRange = Math.max(coverRange, i + nums[i]);
  11. if (coverRange >= nums.length - 1) {
  12. return true;
  13. }
  14. }
  15. return false;
  16. }
  17. }

 

  1. class Solution {
  2. public int jump(int[] nums) {
  3. if (nums == null || nums.length == 0 || nums.length == 1) {
  4. return 0;
  5. }
  6. //记录跳跃的次数
  7. int count=0;
  8. //当前的覆盖最大区域
  9. int curDistance = 0;
  10. //最大的覆盖区域
  11. int maxDistance = 0;
  12. for (int i = 0; i < nums.length; i++) {
  13. //在可覆盖区域内更新最大的覆盖区域
  14. maxDistance = Math.max(maxDistance, i+nums[i]);
  15. //说明当前一步,再跳一步就到达了末尾
  16. if (maxDistance >= nums.length-1) {
  17. count++;
  18. break;
  19. }
  20. //走到当前覆盖的最大区域时,更新下一步可达的最大区域
  21. if (i == curDistance) {
  22. curDistance = maxDistance;
  23. count++;
  24. }
  25. }
  26. return count;
  27. }
  28. }

 

  1. class Solution {
  2. public int largestSumAfterKNegations(int[] nums, int k) {
  3. // 排序,把可能有的负数排到前面
  4. Arrays.sort(nums);
  5. int sum = 0;
  6. for (int i = 0; i < nums.length; i++) {
  7. // 贪心:如果是负数,而k还有盈余,就把负数反过来
  8. if (nums[i] < 0 && k > 0) {
  9. nums[i] = -1 * nums[i];
  10. k--;
  11. }
  12. sum += nums[i];
  13. }
  14. Arrays.sort(nums);
  15. // 如果k没剩,那说明能转的负数都转正了,已经是最大和,返回sum
  16. // 如果k有剩,说明负数已经全部转正,所以如果k还剩偶数个就自己抵消掉,不用删减,如果k还剩奇数个就减掉2倍最小正数。
  17. return sum - (k % 2 == 0 ? 0 : 2 * nums[0]);
  18. }
  19. }
  20. class Solution {
  21. public int largestSumAfterKNegations(int[] nums, int K) {
  22. // 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
  23. nums = IntStream.of(nums)
  24. .boxed()
  25. .sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
  26. .mapToInt(Integer::intValue).toArray();
  27. int len = nums.length;
  28. for (int i = 0; i < len; i++) {
  29. //从前向后遍历,遇到负数将其变为正数,同时K--
  30. if (nums[i] < 0 && K > 0) {
  31. nums[i] = -nums[i];
  32. K--;
  33. }
  34. }
  35. // 如果K还大于0,那么反复转变数值最小的元素,将K用完
  36. if (K % 2 == 1) nums[len - 1] = -nums[len - 1];
  37. return Arrays.stream(nums).sum();
  38. }
  39. }

 

  1. // 解法2
  2. class Solution {
  3. public int canCompleteCircuit(int[] gas, int[] cost) {
  4. int curSum = 0;
  5. int totalSum = 0;
  6. int index = 0;
  7. for (int i = 0; i < gas.length; i++) {
  8. curSum += gas[i] - cost[i];
  9. totalSum += gas[i] - cost[i];
  10. if (curSum < 0) {
  11. index = (i + 1) % gas.length ;
  12. curSum = 0;
  13. }
  14. }
  15. if (totalSum < 0) return -1;
  16. return index;
  17. }
  18. }

 

  1. class Solution {
  2. public boolean lemonadeChange(int[] bills) {
  3. int cash_5 = 0;
  4. int cash_10 = 0;
  5. for (int i = 0; i < bills.length; i++) {
  6. if (bills[i] == 5) {
  7. cash_5++;
  8. } else if (bills[i] == 10) {
  9. cash_5--;
  10. cash_10++;
  11. } else if (bills[i] == 20) {
  12. if (cash_10 > 0) {
  13. cash_10--;
  14. cash_5--;
  15. } else {
  16. cash_5 -= 3;
  17. }
  18. }
  19. if (cash_5 < 0 || cash_10 < 0) return false;
  20. }
  21. return true;
  22. }
  23. }

 

 

 

 

 

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/981151
推荐阅读
相关标签
  

闽ICP备14008679号