代码随想录算法训练营第三十四天| 1005.K次取反后最大化的数组和、134. 加油站、 135. 分发糖果

1005

题目:

给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

  • 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。

重复这个过程恰好 k 次。可以多次选择同一个下标 i 。以这种方式修改数组后,返回数组 可能的最大和 。

题目链接:1005. K 次取反后最大化的数组和 - 力扣(LeetCode)

思路:

贪心,先从小到大排序,然后从i=0开始操作直到num[i]大于0,排序,如果此时k仍然大于0就改变nums[0]。

详情:代码随想录 (programmercarl.com)

代码:

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

134

题目:

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

题目链接:134. 加油站 - 力扣(LeetCode)

思路:

1.使用暴力法两层for循环模拟,要注意边界条件,小部分数据超时

2.贪心策略,先将两个数组的差做累加,同时记录其中累加和的最小值,如果累加值小于0则不满足,如果最小值大于0则是从0加油站,然后从后往前遍历直到最小值加差值能被填为大于等于0,就是这个加油站

3贪心策略,将两个数组的差做累加,如果小于0则这个区间都不满足。从i+1开始继续,循环上述步骤直到结束。如果累计值小于0不满足,否则返回i+1。

详情:代码随想录 (programmercarl.com)

代码:

//暴力法
class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int res [] =new int [gas.length];
        List <Integer> a = new ArrayList<Integer>();
        for(int i = 0;i<gas.length;i++)
        {
            res[i]=gas[i]-cost[i];
            if(res[i]>=0)
                a.add(i);
        }
        if(a.size()==0) return -1;
        for(int i =0 ; i <a.size();i++)
        {
            int index =a.get(i)+1;//当前加油站
            int cur = res[index-1];//当前油箱油量
            int flag = 0;
            int index_1=index;//起始模拟的下标
            int index_2 =index-2;//成功终止的下标
            if(index_2==-1) 
            {
                index_2=gas.length-1;
                flag=1;
            }
            if(index ==gas.length)
            {
                index_1=0;
                flag = 1;
            }               
            for(int j = index_1 ;j<gas.length;j++)
            {
                cur = cur+res[j];
                if(cur<0)   break; //此次出发加油站不满足
                if((j==(gas.length-1)) && flag==0)
                {
                    flag=1;
                    j=-1;
                }           
                if(flag==1 && j==index_2)
                    return index-1;
            }
        }
        return -1;
    }
}

135

题目:

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 

题目链接:135. 分发糖果 - 力扣(LeetCode)

思路:

好难想,既要比较左边,还要比较右边,最后取它两的最大值。

详情:代码随想录 (programmercarl.com)

代码:

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;
    }
}

代码是随想录中的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值