贪心算法part04 算法

本文介绍了如何使用贪心算法解决LeetCode中的三个问题:柠檬水找零(860),根据身高重建队列(406),以及用最少数量的箭引爆气球(452),展示了如何通过优化策略实现高效求解。
摘要由CSDN通过智能技术生成

贪心算法part04 算法

● 860.柠檬水找零
● 406.根据身高重建队列
● 452. 用最少数量的箭引爆气球

1.leetcode 860.柠檬水找零

https://leetcode.cn/problems/lemonade-change/description/

class Solution {
    public boolean lemonadeChange(int[] bills) {
        //看能不能找零
        //bills[i] 不是 5 就是 10 或是 20 ,已经固定好了
        //遇见5,我们就直接收起来
        //遇见10我们就找张5块的给他,10元收起来
        //遇见20我们就两种找零方式,优先10+5,再5+5+5
        
        //计每种面额的数量
        int five=0;
        int ten=0;
        int twenty=0;
        for(int i=0;i<bills.length;i++){
            if(bills[i]==5){
                five++;
            }else if(bills[i]==10){
                if(five>0){
                    //有钱可以找
                    five--;
                    ten++;
                }else{
                    //没钱可以找零
                    return false;
                }
            }else if(bills[i]==20){
                if(ten>0&&five>0){
                    //可以找
                    ten--;
                    five--;
                    twenty++;
                }else if(five>=3){
                    //三张五块的,也可以找
                    five=five-3;
                    twenty++;
                }else{
                    //没得找零
                    return false;
                }
            }
        }
        //上面都没有返回false
        //那就是都能被找零
        return true;
    }
}

2.leetcode 406.根据身高重建队列

https://leetcode.cn/problems/queue-reconstruction-by-height/description/

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        //身高从大到小排,(身高相同的k小的站i前面)
        Arrays.sort(people,(a,b)->{
            if(a[0]==b[0]){
                //身高相同
                return a[1]-b[1];
            }
            return b[0]-a[0];//b-a是降序排列
        });
        //定义一个存放结果的变量
        LinkedList<int[]> result=new LinkedList<>();
        for(int i=0;i<people.length;i++){
            //将k有值的,不为0的插到对应的位置
            //记录要插入的位置
            int pesition=people[i][1];//也就是k
            result.add(pesition,people[i]);//将值插到指定index去  index,value
        }
        return result.toArray(new int[people.length][]);
    }
}

3.leetcode 452. 用最少数量的箭引爆气球

https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/description/

class Solution {
    public int findMinArrowShots(int[][] points) {
        //画图模拟过程才好容易理解
        //如果都没气球,那么都不用射箭
        if(points.length==0){return 0;}
        //对气球的左边界进行排序
        Arrays.sort(points,(a,b)->Integer.compare(a[0],b[0]));
        //point气球不为空至少需要一只箭
        int count=1;
        for(int i=1;i<points.length;i++){
            //i从1开始
            //如果现在的气球左区间大于上一个气球的右区间
            if(points[i][0]>points[i-1][1]){
                //证明没有重叠
                count++;
            }else{
                //气球重叠了,那就更新右区间
                points[i][1]=Math.min(points[i][1],points[i-1][1]);
            }
        }
        return count;
    }
}
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贪心算法是一种常用的算法思想,它通常用于求解最优化问题。贪心算法的基本思想是:每一步都选择当前状态下最优的解,最终得到全局最优解。但是,贪心算法并不是所有问题都适用,有些问题需要进行证明才能确定贪心算法的正确性。 其中,反证法是一种常用的证明方法。反证法的基本思想是:假设所要证明的命题不成立,然后推导出一个矛盾的结论,从而证明原命题成立。 在贪心算法中,反证法通常用于证明贪心选择性质和最优子结构性质。具体来说,假设贪心算法得到的解不是最优解,然后推导出一个矛盾的结论,从而证明贪心算法得到的解是最优解。 举个例子,假设有一个背包问题,要求在背包容量为C的情况下,选择一些物品放入背包中,使得背包中物品的总价值最大。每个物品有两个属性:重量w和价值v。贪心算法可以选择每次选择单位重量价值最大的物品放入背包中。我们可以使用反证法来证明这个贪心算法的正确性: 假设贪心算法得到的解不是最优解,即存在一种更优的解。我们假设这个更优的解选择了物品i和物品j,但是贪心算法没有选择物品j,而是选择了物品k。那么我们可以得到以下两个不等式: v[i]/w[i] > v[j]/w[j] (物品i的单位重量价值大于物品j的单位重量价值) v[i]/w[i] < v[k]/w[k] (物品i的单位重量价值小于物品k的单位重量价值) 将这两个不等式相乘,得到: v[i]*v[k] > v[j]*w[i] 由于v[i]、v[j]、w[i]、w[j]都是正数,所以上式成立。但是,我们知道贪心算法选择物品i和物品k的总价值一定大于选择物品i和物品j的总价值,因为: v[i]*w[k] + v[k]*w[i] > v[i]*w[j] + v[j]*w[i] 这与上式矛盾,因此假设不成立,贪心算法得到的解是最优解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值