算法通关村第19关【白银】| 动态规划高频问题

news2024/11/17 7:48:46

1.零钱兑换

思路:

确定dp:这里是最少硬币的个数,不是种类

确定递推公式:dp[j] = Math.min(dp[j],dp[j-coins[i]]+1),不要当前硬币dp[j]还是保持以前的组合方法,要当前硬币dp[j-coins[i]]+1

确定初始化:dp[0]=0,其他的都得初始化最大值

确定遍历顺序:组合排列都无所谓,保证完全背包从前往后即可

class Solution {
    public int coinChange(int[] coins, int amount) {
        int max = amount + 1;
        int[] dp = new int[amount+1];
        Arrays.fill(dp,max);
        dp[0] = 0;
        for(int i = 1;i<amount+1;i++){
            for(int j = 0;j<coins.length;j++){
                if(coins[j]<=i)
                    dp[i] = Math.min(dp[i],dp[i-coins[j]]+1);
            }
        }
        return dp[amount] >= max?-1:dp[amount];
    }
}

 2.最长连续递增序列

思路:

dp:当前最长的递增子序列长度

递增的时候:dp[i] = dp[i-1]+1

class Solution {
    public int findLengthOfLCIS(int[] nums) {
        int[] dp = new int[nums.length];
        int res = 1;
        for(int i = 0;i<nums.length;i++){
            dp[i] = 1;
        }
        for(int i = 1;i<nums.length;i++){
            if(nums[i]>nums[i-1]){
                dp[i] = dp[i-1] + 1;
            }
            res = res > dp[i] ? res : dp[i];
        }
        return res;
    }
}

3.最长递增子序列

思路:

确定dp:包含当前数字的最长递增子序列长度

确定递推公式:dp[i] = Math.max(dp[i],dp[j]+1),

确定初始化:dp[i]=1,只包含当前元素长度为1

确定遍历顺序:后面的dp依赖前面的得出从前往后

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp =new int[nums.length];
        Arrays.fill(dp,1);
        int res = 0;
        for(int i = 0;i<nums.length;i++){
            for(int j = 0;j<i;j++){
                if(nums[i]>nums[j]){
                    dp[i] = Math.max(dp[i],dp[j]+1);
                }          
            }
            res = Math.max(res,dp[i]);
        }
        return res;
    }
}

4.完全平方数

思路:

确定dp:当前数字最少组成数量

确定递推公式:dp[i] = Math.min(dp[i],dp[i-j*j]+1);当前和取j*j之中的最小

确定初始化:dp[0]=0,dp为max

确定遍历顺序:后面的dp依赖前面的得出从前往后

class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n+1];
        Arrays.fill(dp,Integer.MAX_VALUE);
        dp[0] = 0;
        for(int i = 1;i<=n;i++){
            for(int j = 1;j*j<=i;j++){
                dp[i] = Math.min(dp[i],dp[i-j*j]+1);
            }
        }
        return dp[n];
    }
}

5.跳跃游戏

思路:

确定dp:当前能跳的最远距离

确定递推公式:dp[i] = Math.max(dp[j],j+nums[j]);

确定初始化:dp[0]=nums[0],dp为0

确定遍历顺序:后面的dp依赖前面的得出从前往后

class Solution {
    public boolean canJump(int[] nums) {
        int len = nums.length;
        if(len == 1){
            return true;
        }
        int[] dp = new int[len];
        Arrays.fill(dp,0);
        dp[0] = nums[0];
        for(int i = 0;i<len;i++){
            for(int j = 0;j<=i;j++){
                dp[i] = Math.max(dp[j],j + nums[j]);
            }
            if(i<len-1&&dp[i]<=i)
                return false;   
        }
        return true;
    }
}

6.解码方法

思路:

确定dp:当前的解码方案数

确定递推公式:dp[i] = dp[i-1]+dp[i-2]

  •         当 i-1 和 i 为0 或者 i 为0且 i-1 和 i 大于26:不符合条件,返回0
  •         当i为0,则dp[i] = dp[i-2]
  •         当i-1为0或者i-1不为0且i-1 和 i 大于26,则dp[i] = dp[i-1]
  •         其他情况,dp[i] = dp[i-1] + dp[i-2]

确定初始化:dp[0]=0

确定遍历顺序:后面的dp依赖前面的得出从前往后

class Solution {
    public int numDecodings(String s) {
        int len = s.length();
        if(s.charAt(0) == '0'){
            return 0;
        }
        if(len == 1){
            return 1;
        }
        int[] dp = new int[len];
        char[] c = s.toCharArray();
        dp[0] = 1;
        if(isAble(c[0],c[1])&&c[1]!='0'){
            dp[1] = 2;
        }else{
            dp[1] = 1;
        }
        if(c[1] == '0'&&!isAble(c[0],c[1])){
            return 0;
        }
        for(int i = 2;i<len;i++){
            if(c[i] == '0' && c[i-1] == '0'|| (c[i] == '0'&&!isAble(c[i-1],c[i]))){
                return 0;
            }
            if(c[i]=='0'){
                dp[i] = dp[i-2];
            }else if(c[i-1] == '0'){
                dp[i] = dp[i-1];
            }else if(isAble(c[i-1],c[i])){
                dp[i] = dp[i-1] + dp[i-2];
            }else{
                dp[i] = dp[i-1];
            }
        }
        return dp[len-1];
    }

    public boolean isAble(char c1,char c2){
        int num1 = c1 - '0';
        if(num1 == 0) return false;
        int num2 = c2 - '0';
        int num = num1*10 + num2;
        return num <=26 ? true : false;
    }
}

 也可以判断不符合的条件,更加简洁

class Solution {
    public int numDecodings(String s) {
        int n = s.length();
        int[] f = new int[n + 1];
        f[0] = 1;
        for (int i = 1; i <= n; ++i) {
            if (s.charAt(i - 1) != '0') {
                f[i] += f[i - 1];
            }
            if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0') <= 26)) {
                f[i] += f[i - 2];
            }
        }
        return f[n];
    }
}

7.不同路径II

思路:

确定dp:能到达当前位置的路径数

确定递推公式: dp[i][j] = dp[i-1][j] + dp[i][j-1];

确定初始化:第一行和第一列为1,注意碰到障碍物后面全是0

确定遍历顺序:后面的dp依赖前面的得出从前往后,从左往右

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length];
        for(int i = 0;i<obstacleGrid[0].length;i++){
            if(obstacleGrid[0][i] == 1){
                break;
            }
            dp[0][i] = 1;
        }
        for(int i = 0;i<obstacleGrid.length;i++){
            if(obstacleGrid[i][0] == 1){
                break;
            }
            dp[i][0] = 1;
        }
        for(int i = 1;i<obstacleGrid.length;i++){
            for(int j = 1;j<obstacleGrid[0].length;j++){
                if(obstacleGrid[i][j] != 1){
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
                }
            }
        } 
        return dp[obstacleGrid.length-1][obstacleGrid[0].length-1];
    }
}

8.滚动数组技巧

思路:

杨辉三角,除了0号位置和i==j的位置是1,其他都是左上角+右上角的值

一般解法:二维数组就是初始化一个dp[i][j],然后逐行遍历相加,输出指定行的值

现在要进行空间优化O(rowIndex)

如果我们使用一个一维数组dp[]:

        从前往后遍历相加:121=>131=>1341 会发现原先的2被覆盖替换为了3,导致后面的数计算错误。这时我们可以使用第二个一维数组来帮助我们记录值

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<Integer> pre = new ArrayList<Integer>();
        for (int i = 0; i <= rowIndex; ++i) {
            List<Integer> cur = new ArrayList<Integer>();
            for (int j = 0; j <= i; ++j) {
                if (j == 0 || j == i) {
                    cur.add(1);
                } else {
                    cur.add(pre.get(j - 1) + pre.get(j));
                }
            }
            pre = cur;
        }
        return pre;
    }
}

        从后往前遍历:121=>31=>331=>1331 会发现左上角和右上角的值并没被覆盖√

class Solution {
    public List<Integer> getRow(int rowIndex) {
        List<Integer> row = new ArrayList<Integer>();
        row.add(1);
        for (int i = 1; i <= rowIndex; ++i) {
            row.add(0);
            for (int j = i; j > 0; --j) {
                row.set(j, row.get(j) + row.get(j - 1));
            }
        }
        return row;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1115884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NFT Insider112:The Sandbox聘请Apple高管担任其首席内容官,YGG 将在菲律宾举办Web3游戏峰会

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members、BeepCrypto联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据&#xff0c;艺术新闻类&#xff0c;游戏新闻类&#xff0c;虚拟世界类&#…

华为eNSP配置专题-浮动路由及BFD的配置

文章目录 华为eNSP配置专题-浮动路由及BFD的配置0、参考文档1、前置环境1.1、宿主机1.2、eNSP模拟器 2、基本环境搭建2.1、基本终端构成和连接2.2、基本终端配置 3、浮动路由配置3.1、浮动路由的基本配置3.2、浮动路由的负载均衡问题3.3、浮动路由的优先级调整 4、BFD的配置4.1…

YOLOv8改进实战 | 更换主干网络Backbone(四)之轻量化模型MobileNetV3

前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…

利用 Pytest Cache Fixture 实现测试结果缓存

前言 接口自动关过程中&#xff0c;经常会遇到这样一些场景&#xff0c;"请求2需要用到请求1响应的数据"&#xff0c;常见的做法&#xff0c;进行用例依赖或者将请求1的响应结果写入一个文件&#xff0c;用到的时候读取文件。当然这都不是这篇文章的重点&#xff0c…

Redis性能滑坡:哈希表碰撞的不速之客【redis第二部分】

Redis性能滑坡&#xff1a;哈希表碰撞的不速之客 前言第一部分&#xff1a;Redis哈希表简介第二部分&#xff1a;哈希表冲突原因第三部分&#xff1a;Redis哈希函数第四部分&#xff1a;哈希表冲突的性能影响第五部分&#xff1a;解决冲突策略第六部分&#xff1a;redis是如何解…

nginx常见报错及解决acme.sh给Nginx配置SSL证书

问题排查&#xff1a; nginx -t //检查配置是否正确只要返回ok就说明配置没问题。 Nginx报错Failed to restart nginx.service: Unit not found 解决方法&#xff1a; 1、在根目录下执行 vim /etc/init.d/nginx2、插入以下代码 #!/bin/sh # nginx - this script starts …

Python rich库

1. 安装 pip install rich Collecting richDownloading rich-13.6.0-py3-none-any.whl.metadata (18 kB) Collecting markdown-it-py>2.2.0 (from rich)Downloading markdown_it_py-3.0.0-py3-none-any.whl.metadata (6.9 kB) Collecting pygments<3.0.0,>2.13.0 (f…

1024程序员节,给大家送份福利

各位“爱码士”们 一年一度的1024程序员节就要到了 提前祝程序猿/媛们节日快乐 除了祝福&#xff0c;肯定少不了福利啦&#xff5e; 废话不多说&#xff0c;直接上福利 知了堂1024加油包 用心成就你的IT梦想 价值9800的程序员助梦加油包 仅需1.24元 内含1024元助学金 …

Sui成为DeFi增长的首选平台

Sui网络在过去的三个月内DeFi活动增长迅速&#xff0c;其中TVL增长了341&#xff05;&#xff0c;交易量增长了229&#xff05;。这一增长对于Sui来说是一个重要的里程碑&#xff0c;它展示了Sui为其DeFi生态中的第三方开发者提供的实用性&#xff0c;以及他们支持数百万用户进…

element-ui 以CDN 方式引入原生js开发的几个别坑 (+vue)

element-ui 以CDN 方式引入原生js开发的几个坑 最近两个月太忙了 忙的没空写文章 两个月赶出来了几个的项目 一个是雪佛兰裸眼3D的一个商品屏幕展示项目 一个是广汽云渲染的一个云看车项目 一个是奥迪中国充电桩的网页开发项目&#xff0c; 奥迪中国做个饭也是目前正在做的 不…

Linux系统编程04

进程的概念 进程&#xff08;动态&#xff09;是一个正在运行的程序&#xff08;静态&#xff09; 多道程序设计缺点&#xff1a; &#xff08;1&#xff09;缺乏隔离&#xff0c;各个程序之间可以直接访问&#xff0c;使用对方的数据 &#xff08;2&#xff09;内存使用率低&a…

正点原子嵌入式linux驱动开发——LED驱动开发

在上一篇笔记中&#xff0c;详细的讲解了字符设备驱动开发步骤&#xff0c;并且用一个虚拟的chrdevbase设备为例完成了第一个字符设备驱动的开发。本章就开始编写第一个真正的Linux字符设备驱动。在正点原子STM32MP157开发板上有一个LED灯&#xff0c;本章就学习一下如何编写Li…

探讨Unity新的收费模式:对开发者与游戏行业的影响、负面因素的解析及面对挑战的建议

本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》采购供应链共享平台人员,财务规则对账人员&#xff0c;物流门禁计量系统对接人员&#xff0c;ERP事业部人员 Unity是一款备受开发者欢迎的跨平台游戏引擎&#xff0c…

基于SSM的台球厅管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

【再识C进阶5(上)】详细介绍C语言文件操作——文件是用于存储数据

前言 &#x1f493;作者简介&#xff1a; 加油&#xff0c;旭杏&#xff0c;目前大二&#xff0c;正在学习C&#xff0c;数据结构等&#x1f440; &#x1f493;作者主页&#xff1a;加油&#xff0c;旭杏的主页&#x1f440; ⏩本文收录在&#xff1a;再识C进阶的专栏&#x1…

成绩查询页面和自助查询方式

科技发展让我们有更多的方式来发布和查询学生成绩。今天&#xff0c;我想向大家介绍什么是成绩查询页面&#xff0c;并分享如何通过各种代码和Excel来实现让学生自助查询成绩。 成绩查询页面是一个专门用来发布和查询学生成绩的网络页面。这个页面具有发布、查询、统计成绩等功…

Vue 3使用 Iconify 作为图标库与图标离线加载的方法、 Icones 开源在线图标浏览库的使用

之前一直naive-ui搭配使用的是xicons&#xff0c;后来发现Iconify支持的图标合集更多&#xff0c;因此转而使用Iconify。 与FontAwesome不同的是&#xff0c;Iconify配合Icones相当于是一个合集&#xff0c;Iconify提供了快捷引入图标的方式&#xff0c;而Icones是一个大的图标…

二、vue基础语法

一、模板语法 1、文本渲染 使用双花括号语法插入文本 <template><div><h3>msg: {{ message }}</h3></div> </template><script> export default {data() {return {message: "输出信息"}} } </script><style s…

SAP 路径及运输功能

一、 概述 SAP的发运功能包括两部份内容&#xff0c;一是运输路径&#xff1b;二是运输功能。运输路径是运输功能的基础。 SAP 中的运输功能是后勤执行的一部分&#xff0c;用于自动计算交货成本&#xff1b;也就是说&#xff0c;SAP 可以让系统自动对销售发货的商品计算运费&…

web APIs——第一天(上)

变量声明的时候建议 const优先&#xff0c;尽量使用const 原因&#xff1a; const语义化更好很多变量我们声明的时候就知道他不会被更改了&#xff0c;那为什么不用const呢&#xff1f;实际开发中也是&#xff0c;比如react框架&#xff0c;基本const如果你有纠结的时候&…