算法day25-贪心(3)

目录

  1. 加油站
  2. 分发糖果
  3. 柠檬水找零
  4. 根据身高重建队列

一、加油站

 https://leetcode.cn/problems/gas-station/description/?envType=problem-list-v2&envId=8At1GmaZ

 

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++){
            int gain = gas[i] - cost[i];
            curSum += gain;
            totalSum += gain;
            if(curSum < 0){
                //只有当走不下去的时候,会尝试换一个出发点
                index = ( i + 1 ) % gas.length;
                curSum = 0;         //重新累计
            }
        }
        if(totalSum < 0)       return -1;       //如果遍历一次后gas比cost要小,则不管从哪个点出发都不囊环路行驶一周
        return index;
    }
}

 

二、分发糖果

https://leetcode.cn/problems/candy/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int candy(int[] ratings) {
        int[] candies = new int[ratings.length];
        Arrays.fill(candies, 1);
        int flag = 0;
        while(true){
            flag = 0;
            for(int i=0; i<ratings.length-1; i++){
                if(ratings[i] > ratings[i+1] && candies[i] <= candies[i+1]){
                    candies[i] = candies[i+1] + 1;
                    flag = 1;
                }else if(ratings[i] < ratings[i+1] && candies[i] >= candies[i+1]){
                    candies[i+1] = candies[i] + 1;
                    flag = 1;
                }
            }
            if(flag == 0){          //一轮都没修改,说明已经满足最终条件了
                break;
            }
        }
        int sum = 0;
        for(int x: candies){
            sum += x;
        }
        return sum;
    }    
}

 

class Solution {
    public int candy(int[] ratings) {
        int len = ratings.length;
        int[] candies = new int[len];
        Arrays.fill(candies,1);         //每个孩子至少有一个糖果
        for(int i=1; i<len; i++){          //从前向后遍历一次,这里只考虑相邻的两个:前面的糖果决定后面的
            //若前面孩子的分数小于后面的孩子分数
            candies[i] = (ratings[i] > ratings[i-1]) ? candies[i-1]+1 : candies[i]; 
        }

        for(int i=len-2; i>=0; i--){
            //从后向前遍历一次,这里是后面的糖果决定前面的
            if(ratings[i] > ratings[i+1]){
                candies[i] = Math.max(candies[i], candies[i+1] + 1);
            }
        }
        int sum = 0;
        for(int x : candies){
            sum += x;
        }
        return sum;
    }
}

 

三、柠檬水找零

 https://leetcode.cn/problems/lemonade-change/?envType=problem-list-v2&envId=8At1GmaZ

 

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++;             //得到一张5元的,不用找零
            }else if(bills[i] == 10){
                five--;             //找零五元
                ten++;              //10元的加一张
            }else if(bills[i] == 20){
                if(ten > 0){        //如果还有10块的
                    ten--;
                    five--;
                }else{
                    five -= 3;
                }
            }
            if(five < 0|| ten < 0)  return false;
        }
        return true;
    }
}

 

四、根据身高重建队列

 https://leetcode.cn/problems/queue-reconstruction-by-height/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        Arrays.sort(people, (a, b) -> a[0] != b[0] ? b[0] - a[0] : a[1] - b[1]);
        List<int[]> res = new LinkedList<>();       //定义结果的
        for(int i=0; i<people.length; i++){
            if(res.size() > people[i][1]){      
                //结果集中元素个数大于第i个人前面应有的人数时,将第i个人插入到结果集的 people[i][1]位置
                res.add(people[i][1], people[i]);
            }else{
                res.add(people[i]);
            }
        }
        return res.toArray(new int[res.size()][]);
    }
}

 

posted @ 2025-05-25 21:27  筱倩  阅读(10)  评论(0)    收藏  举报