海智算法训练营第三十三天 | 第八章 贪心算法 part03 | ● 1005.K次取反后最大化的数组和 ● 134. 加油站● 135. 分发糖果

今日任务:

1.k次取反后最大化数组和

2.贪心解决加油站问题

3.左右边界分别处理------分发糖果

1.k次取反后最大化数组和

力扣题目链接

这道题比较简单就不多说了。

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        Arrays.sort(nums);
        for (int i = 0; i < nums.length && nums[i] < 0 && k > 0; i++) {
            nums[i] = -nums[i];
            k--;
        }
        Arrays.sort(nums);
        if(k % 2 == 1)  nums[0] = -nums[0];
        int sum = Arrays.stream(nums).sum();
        return sum;
    }
}

2.贪心解决加油站问题

力扣题目链接

题目要求:

这是此题的贪心解法,先把每个站点总需要花费的油量计算出来,如果所有油量加起来是小于零的那么不管怎样都是不能转一圈的。

这道题可以这样理解,找到curSum的最小值,从该最小值的后一个值开始走就对了,理解成,你需要在前面累积最多的油量,给这个消耗最多的点去用。

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int curSum = 0 , totalSum = 0 , start = 0;
        for (int i = 0; i < gas.length; i++) {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0){
                start = i+1;
                curSum = 0;
            }
        }
        if (totalSum < 0)   return -1;
        return start;
    }
}

此外另外一种方法也很好理解但是不是贪心的算法:

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int sum = 0;
        int min = 0;
        for (int i = 0; i < gas.length; i++) {
            sum += (gas[i] - cost[i]);
            min = Math.min(sum, min);
        }

        if (sum < 0) return -1;
        if (min >= 0) return 0;

        for (int i = gas.length - 1; i > 0; i--) {
            min += (gas[i] - cost[i]);
            if (min >= 0) return i;
        }

        return -1;
    }
}

直接从全局进行贪心选择,情况如下:

  • 情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的

  • 情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。

  • 情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。(主要是这里,从后往前遍历和负数进行抵消)

3.左右边界分别处理------分发糖果

力扣题目

题目描述:

首先创建数组,给每个位置都赋值为1,先看左边,从左到右如果右边的数比左边大,那么就+1,再看右边,从右到左,如果左边比右边大,那么这时候如果想要满足左边又满足右边的条件的话那就需要选取当前的最大值,这样才不会冲突。

看评论有个比较好理解的说法:两种情况要同时满足,原先小的糖果数我就可以满足,我更大的糖果数怎么就满足不了了呢?

class Solution {
    public int candy(int[] ratings) {
        int res[] = new int[ratings.length];
        Arrays.fill(res,1);
        for (int i = 1; i < ratings.length; i++) {
            if(ratings[i] > ratings[i-1]){
                res[i] = res[i-1] + 1;
            }
        }

        for (int i = ratings.length-2; i >= 0; i--) {
            if(ratings[i] > ratings[i+1]){
                res[i] = Math.max(res[i] , res[i+1] + 1);
            }
        }

        return Arrays.stream(res).sum();
    }
}

学习时长:2h

总结:此次学习贪心如何解决区间问题,以及遇到需要左右判断的题目怎么去逐一分开去做。

相关推荐
Ocean☾几秒前
前端基础-html-注册界面
前端·算法·html
顶呱呱程序9 分钟前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
爱吃生蚝的于勒30 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~34 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
lc寒曦1 小时前
【VBA实战】用Excel制作排序算法动画
排序算法·excel·vba
王哈哈^_^1 小时前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城1 小时前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz1 小时前
STL--哈希
c++·算法·哈希算法
kingmax542120082 小时前
初三数学,最优解问题
算法