LeetCode Day34 1005&134&135

57 阅读1分钟
1005. K 次取反后最大化的数组和

贪心思路:把最小的负数翻转就可以得到局部最大数值,进而得到全局最大的数组和。

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

            nums[idx] = -nums[idx];
        }

        int sum = 0;
        for(int i = 0; i < nums.length; i ++){
            sum += nums[i];
        }
        return sum;
    }
}
134. 加油站

如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。每个加油站的剩余量rest[i]为gas[i] - cost[i]。i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。

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

        if(totalSum < 0) return -1;
        return index;
    }
}
135. 分发糖果

一开始看完例子以后没想懂小孩的评分在这里起到什么作用。。因为不管评分高低,分糖果多的依据应该是一个小孩周围的人多少。后面再看其实是局部评分高且周围小朋友多的孩子分到的糖果才多,所以如果ratings[i] > ratings[i - 1] 那么[i]的糖 一定要比[i - 1]的糖多一个,那么贪心:candyVec[i] = candyVec[i - 1] + 1。此时局部最优:只要右边评分比左边大,右边的孩子就多一个糖果,全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果。局部最优可以推出全局最优。

class Solution {
    public int candy(int[] ratings) {
        int len = ratings.length;
        int[] candyVec = new int[len];
        candyVec[0] = 1;
        for(int i = 1; i < len; i ++){
            candyVec[i] = (ratings[i] > ratings[i - 1]) ? candyVec[i-1] + 1 : 1;
        }

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

        int ans = 0;
        for(int num : candyVec){
            ans += num;
        }

        return ans;
    }
}