代码随想录算法训练营day29|贪心算法part03

第一题:134. Gas Station

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

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

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

  • 情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。

    // 解法1
    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;
        }
    }
    
    // 解法2
    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. Candy
    这题没什么思路,要考虑两边的情况好复杂,直接看了题解:

    class Solution {
        /**
             分两个阶段
             1、起点下标1 从左往右,只要 右边 比 左边 大,右边的糖果=左边 + 1
             2、起点下标 ratings.length - 2 从右往左, 只要左边 比 右边 大,此时 左边的糖果应该 取本身的糖果数(符合比它左边大) 和 右边糖果数 + 1 二者的最大值,这样才符合 它比它左边的大,也比它右边大
        */
        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;
        }
    }

第三题:860. Lemonade Change

这题还是比较简单的,只需要监控5美元和10美元的情况就好了,然后在20元的时候优先使用10美元的情况。

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int five = 0;
        int ten = 0;

        for (int i = 0; i < bills.length; i++) {
            if (bills[i] == 5) {
                five++;
            } else if (bills[i] == 10) {
                five--;
                ten++;
            } else if (bills[i] == 20) {
                if (ten > 0) {
                    ten--;
                    five--;
                } else {
                    five -= 3;
                }
            }
            if (five < 0 || ten < 0) return false;
        }
        
        return true;
    }
}

 

第四题:406.Queue Reconstruction by Height

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 身高从大到小排(身高相同k小的站前面)
        Arrays.sort(people, (a, b) -> {
            if (a[0] == b[0]) return a[1] - b[1];   // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列
            return b[0] - a[0];   //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列
        });

        LinkedList<int[]> que = new LinkedList<>();

        for (int[] p : people) {
            que.add(p[1],p);   //Linkedlist.add(index, value),會將value插入到指定index裡。
        }

        return que.toArray(new int[people.length][]);
    }
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值