首页 > 编程语言 >LeetCode——贪心算法总结

LeetCode——贪心算法总结

时间:2023-04-04 18:05:10浏览次数:44  
标签:10 硬币 int memo coins 算法 amount LeetCode 贪心


贪心算法的主要的解题目的思路是:

 

860. 柠檬水找零

这道题算是生活中很常见的一道题,对于每一个顾客如果我们都有足够的零钱给他找零,那么就返回true,只要有一个顾客没有足够的零钱找给他就返回false。顾客只能有3种纸币,5元,10元,20元。我们要统计5元和10元的数量,20元的不需要统计,因为20元没法找给别人。

顾客给5元,5元的数量加1

顾客给10元,5元的数量减1(减完之后再判断5元的数量,如果小于0,说明5元的不够了,没法给顾客找零了,直接返回false)

顾客给20元,根据生活常识,如果有10元的,应该先找他10元的,然后再找他一个5元的。如果没有10元的就找他3个5元的,然后再判断5元的数量,如果小于0直接返回false。

package 计算机程序算法分类.贪心算法问题;

/**
 * @Classname 柠檬水找零
 * @Description TODO
 * @Date 2021/5/17 10:04
 * @Created by xjl
 */
public class 柠檬水找零 {
    public boolean lemonadeChange(int[] biils){
        //停机的店员拥有的5和10的数据量 不用统计的20的 因为不会需要找人家20的元 就是的没有比20大的钱
        int five=0,ten=0;
        for (int bill:biils){
            if (bill==5){
                //如果顾客使用的是5块的不需要找零 数量加1就行
                five++;
            }else if (bill==10){
                //如果是10需要找5块 所以是的5的数量减1 10的数量加1
                five--;
                ten++;
            }else if (ten>0){
                //否则是的我们需要的是减少10 和5块的各一个
                ten--;
                five--;
            }else {
                //否则是的如果两个都没有的话的 那就是的减少三个的5块的
                five-=3;
            }
            
            if (five<0){
                //直接判断的5元的数量的 如果是5元的数量是小于0 的话 那么就没法给顾客找零了那就是的返回是false 
                return false;
            }
        }
        return true;
    }
}

455. 分发饼干

 

 

322. 零钱兑换

LeetCode——贪心算法总结_递归

可以看出在进行递归的时候,有很多重复的节点要进行操作,这样会浪费很多的时间。使用数组 memo[ ] 来保存节点的值,memo[n]表示钱币 nnn 可以被换取的最少的硬币数,不能换取就为 −1,findWay 函数的目的是为了找到 amount 数量的零钱可以兑换的最少硬币数量,返回其值 int,在进行递归的时候,memo[n]被复制了,就不用继续递归了,可以直接的调用 。

/**
 * Copyright (C), 2018-2020
 * FileName: 零钱兑换
 * Author:   xjl
 * Date:     2020/9/13 14:28
 * Description:
 */
package 计算机程序算法分类.贪心算法问题;

public class 零钱兑换 {
    int[] memo;//在进行递归的时候,memo[n]被复制了,就不用继续递归了,可以直接的调用

    public int coinChange(int[] coins, int amount) {
        if (coins.length == 0) {
            return -1;
        }
        memo = new int[amount];

        return findWay(coins, amount);
    }

    // memo[n] 表示钱币n可以被换取的最少的硬币数,不能换取就为-1
    // findWay函数的目的是为了找到 amount数量的零钱可以兑换的最少硬币数量,返回其值int
    public int findWay(int[] coins, int amount) {
        if (amount < 0) {
            return -1;
        }
        if (amount == 0) {
            return 0;
        }
        // 记忆化的处理,memo[n]用赋予了值,就不用继续下面的循环
        // 直接的返回memo[n] 的最优值
        if (memo[amount - 1] != 0) {
            return memo[amount - 1];
        }
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < coins.length; i++) {
            int res = findWay(coins, amount - coins[i]);
            if (res >= 0 && res < min) {
                min = res + 1; // 加1,是为了加上得到res结果的那个步骤中,兑换的一个硬币
            }
        }
        memo[amount - 1] = (min == Integer.MAX_VALUE ? -1 : min);
        return memo[amount - 1];
    }
}

另一种实现:memo[i]有两种实现的方式,去两者的最小值,包含当前的 coins[i],那么剩余钱就是 i−coins[i],这种操作要兑换的硬币数是 memo[i−coins[j]]+1,不包含,要兑换的硬币数是 memo[i]。

class Solution {
    public int coinChange(int[] coins, int amount) {
        // 自底向上的动态规划
        if(coins.length == 0){
            return -1;
        }

        // memo[n]的值: 表示的凑成总金额为n所需的最少的硬币个数
        int[] memo = new int[amount+1];
        // 给memo赋初值,最多的硬币数就是全部使用面值1的硬币进行换
        // amount + 1 是不可能达到的换取数量,于是使用其进行填充
        Arrays.fill(memo,amount+1);
        memo[0] = 0;
        for(int i = 1; i <= amount;i++){
            for(int j = 0;j < coins.length;j++){
                if(i - coins[j] >= 0){
                    // memo[i]有两种实现的方式,
                    // 一种是包含当前的coins[i],那么剩余钱就是 i-coins[i],这种操作要兑换的硬币数是 memo[i-coins[j]] + 1
                    // 另一种就是不包含,要兑换的硬币数是memo[i]
                    memo[i] = Math.min(memo[i],memo[i-coins[j]] + 1);
                }
            }
        }

        return memo[amount] == (amount+1) ? -1 : memo[amount];
    }
}

518. 零钱兑换 II

这里就是的一个完全的背包问题的。请一定要去的理解的背包问题的相关的解答和变式。背包问题的视频:https://www.bilibili.com/video/BV1K4411X766?from=search&seid=11709794381262748318

416. 分割等和子集

494. 目标和

322. 零钱兑换

518. 零钱兑换 II

377. 组合总和 Ⅳ

LeetCode——贪心算法总结_贪心算法_02

class Solution {

    public int change(int amount, int[] coins) {

        int n = coins.length;
        int[][] dp = new int[n + 1][amount + 1];

        for (int i=0;i<=n;i++) {

            dp[i][0] = 1;
        }

        for (int i=1;i<=n;i++) {

            for (int j=1;j<=amount;j++) {

                if (j < coins[i - 1]) {

                    dp[i][j] = dp[i - 1][j]; 
                } else {

                    dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i - 1]];
                }
            }
        }
        return dp[n][amount];
    }
}

 330. 按要求补齐数组

 

 

 

 

标签:10,硬币,int,memo,coins,算法,amount,LeetCode,贪心
From: https://blog.51cto.com/u_13643065/6169221

相关文章

  • 最全综述 | 图像分割算法
    图像分割是计算机视觉研究中的一个经典难题,已经成为图像理解领域关注的一个热点,图像分割是图像分析的第一步,是计算机视觉的基础,是图像理解的重要组成部分,同时也是图像处理中最困难的问题之一。所谓图像分割是指根据灰度、彩色、空间纹理、几何形状等特征把图像划分成若干个互不相......
  • 如何基于AI算法实现智慧工厂视频大数据智能预警平台搭建?
    当前我国正处于数字经济高速发展的时代,企业正面临着数字化“转型升级”的需求。那么,工厂该如何实现智能化转型目标呢?EasyCVR视频融合平台与AI智能分析网关,融合了边缘AI智能识别技术,部署了多种AI算法,能实现人脸、人体、车辆、物体、行为等智能检测,在工厂的智慧转型场景中发挥着重要......
  • #yyds干货盘点# LeetCode程序员面试金典:最接近的三数之和
    题目:给你一个长度为n的整数数组 nums 和一个目标值 target。请你从nums中选出三个整数,使它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在恰好一个解。 示例1:输入:nums=[-1,2,1,-4],target=1输出:2解释:与target最接近的和是2(-1+2+1=2)......
  • #yyds干货盘点# LeetCode面试题:二进制求和
    1.简述:给你两个二进制字符串a和b,以二进制字符串的形式返回它们的和。 示例 1:输入:a="11",b="1"输出:"100"示例 2:输入:a="1010",b="1011"输出:"10101"2.代码实现:classSolution{publicStringaddBinary(Stringa,Stringb){......
  • 第三届人工智能,大数据与算法国际学术会议 (CAIBDA 2023)
    第三届人工智能,大数据与算法国际学术会议(CAIBDA2023)​大会官网:http://www.caibda.org/大会时间:2023年6月16-18日大会地点:中国郑州截稿日期:2023年6月10日接受/拒稿通知:投稿后1周内提交检索:EICompendex,Scopus往届检索记录:CAIBDA2021| IEEEXplore | EICompende......
  • 【ACM算法竞赛日常训练】DAY10题解与分析【月月给华华出题】【华华给月月出题】| 筛法
    DAY10共2题:月月给华华出题华华给月月出题难度较大。......
  • 4.4学习总结(虚拟试衣算法初步框架构思)
    昨天上台演示了项目框架并且讲述了未来对项目规划的构思,我们组是最后一组,整体等待过程还是很煎熬的比我们队优秀的作品有很多,所以还是很有压力的不过我们会尽力在接下来的时间内,争取完成所介绍的所有功能......
  • 算法训练——剑指offer(模拟算法)
    摘要一、模拟算法原理与解题方法二、模拟算法练习题目2.1顺时针打印矩阵顺时针打印矩阵_牛客题霸_牛客网解题思路:递归的思想和非递归的思想相差不大,递归是首先打印最外层的元素,将内层的矩阵作为一个全新的矩阵进行递归。对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当......
  • 算法训练——剑指offer(排序算法)摘要
    摘要一、排序算法原理与解题方法二、排序算法练习题目2.1数组中重复的数字数组中重复的数字_牛客题霸_牛客网package排序算法;importjava.util.ArrayList;/***@ClassnameJZ3数组中重复的数字*@DescriptionTODO*@Date2022/2/49:20*@Createdbyxjl*/publi......
  • 算法从入门到精通:选择排序
    一、排序和算法排序是算法中的一部分,也叫排序算法。算法一般用来处理数据,而数据的处理最好是要找到他们的规律,这个规律中有很大一部分就是要进行排序,所以需要有排序算法。本节讲解的是选择排序,从选择排序开始认识排序的一些基础概念。之所以将选择排序作为排序的入门,原因是选择排......