dp入门(二)

news2025/8/13 22:29:49

目录

45、跳跃计划

53、最大子数组和

55、跳跃游戏

62、不同路径

 63、不同路径2

 64、最小路径和

 70、爬楼梯

 72、编辑距离

84、柱形图中最大的矩形

85、最大矩形

 4721、排队


45、跳跃计划

 

当前可移动距离尽可能多走,如果还没到终点,步数再加一。整体最优:一步尽可能多走,从而达到最小步数。

思路虽然是这样,但在写代码的时候还不能真的就能跳多远跳远,那样就不知道下一步最远能跳到哪里了。

所以真正解题的时候,要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!

这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。

如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。

class Solution {
    public int jump(int[] nums) {
       int next = 0;
       int ans = 0;
       int end = 0;
        int n = nums.length;
        for (int i = 0; i < n - 1; i ++) {
           next = Math.max(next,nums[i] + i);
           if (i == end) {
               ans ++;
               end = next;
           }
        }
        return ans;
    }
}

53、最大子数组和

贪心思路:当我们连续子段和是负数时,我们是没必要留给下一个数的,因为下一个数不要这一段的和肯定更大,因此我们发现如果sum已经小于0了,我们就留给下一段一个0,每次更新最大值就行

class Solution {
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        int res = Integer.MIN_VALUE;
        for (int i = 0,sum = 0; i < n; i ++) {
            sum += nums[i];
            res = Math.max(res,sum);
            if (sum < 0) sum = 0;
        }
        return res;
    }
}

动态规划:f[i] 表示nums中以i结尾的区间中最大和,f[i] 可以拆分为长度为1和长度大于1的区间,那么我们可以得到 f[i] 可以由 nums[i] 或者 f[i - 1] + nums[i]转移,两边取掉 nums[i],那就成了 nums[i - 1] + max(f[i - 1],0),我们每次遇到的都是 f[i - 1] ,因此可以用 last 来替换!

class Solution {
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        int res = Integer.MIN_VALUE;
        int last = 0;
        for (int i = 0; i < n; i ++) {
            last = Math.max(last,0) + nums[i];
            res = Math.max(res,last);
        }
        return res;
    }
}

55、跳跃游戏

 思路:暴力解法,记录我们可以到达的最远的点,如果我们到达了最远的点还不能到终点,就返回false ,否则返回true

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        int end = 0;
        for (int i = 0; i < n; i ++) {
            end = Math.max(end,nums[i] + i);
            if (i == end && i != n - 1) return false; 
        }
        return true;
    }
}

62、不同路径

动态规划模板题,任何学动态规划的童鞋都不能没做过这道题!!!!

想要求dp[i][j],只能有两个方向来推导出来,即dp[i - 1][j] 和 dp[i][j - 1]。

此时在回顾一下 dp[i - 1][j] 表示啥,是从(0, 0)的位置到(i - 1, j)有几条路径,dp[i][j - 1]同理。

那么很自然,dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。

class Solution {
    public int uniquePaths(int m, int n) {
        int[] f = new int[n];
        for (int i = 0; i < m; i ++) {
            for (int j = 0; j < n; j ++) {
                if (i == 0 && j == 0) f[j] = 1;
                else if (j > 0) {
                    f[j] += f[j - 1];
                }
            }
        }
        return f[n - 1];
    }
}

加了维度压缩,因为是有一层是上一层转移,j 没变,但我记得比赛时候这题有可能爆int。。。。。

 63、不同路径2

 思路:一模一样,如果当前格子不是障碍物,它才有所谓的路径数量

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int n = obstacleGrid.length;
        int m = obstacleGrid[0].length;
        int[][] f = new int[n][m];
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < m; j ++) {
                if (obstacleGrid[i][j] == 0) {
                    if (i == 0 && j == 0) f[i][j] = 1;
                    else {
                        if (i > 0) f[i][j] += f[i - 1][j];
                        if (j > 0) f[i][j] += f[i][j - 1];
                    }
                }
            }
        }
        return f[n - 1][m - 1];
    }
}

 64、最小路径和

 思路:这三道题转移方程其实都是一样的,这道题唯一不同的点在于我们求得是最小值,不能让默认初始化为0干扰我们最终答案,因此我们初始化为无穷即可

class Solution {
    public int minPathSum(int[][] grid) {
        int n = grid.length;
        int m= grid[0].length;
        int[][] f = new int[n][m];
        for (int i = 0; i < n; i ++) Arrays.fill(f[i],0x3f3f3f3f);
        f[0][0] = grid[0][0];
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < m; j ++) {
                if (i > 0) f[i][j] = Math.min(f[i][j],f[i - 1][j] + grid[i][j]);
                if (j > 0) f[i][j] = Math.min(f[i][j],f[i][j - 1] + grid[i][j]);
            }
        }
        return f[n - 1][m - 1];
    }
}

 70、爬楼梯

 思路:同样的,我们f【i】可以由它的前一个(i - 1)跳一步或者 i - 2 (跳两步)得来,累加即可

class Solution {
    public int climbStairs(int n) {
        if (n == 0 || n == 1) return 1;
        int[] f = new int[n + 1];
        f[0] = 1;
        f[1] = 1;
        for (int i = 2 ; i <= n; i ++) {
            f[i] += f[i - 1] + f[i - 2];
        }
        return f[n];
    }
}

我们为了省空间可以用a,b来代替

class Solution {
    public int climbStairs(int n) {
        if (n == 0 || n == 1) return 1;
        int[] f = new int[n + 1];
        int a = 1;
        int b = 1;
        for (int i = 2 ; i <= n; i ++) {
            int c = a + b;
            a = b;
            b = c;
        }
        return b;
    }
}

 72、编辑距离

转移方程如上图所示,初始化记得我们每一个有意义字符串对应另一个字符串为0时的值应该时 有意义字符串的长度(删)

class Solution {
    public int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();
        word1 = " " + word1;
        word2 = " " + word2;
        int[][] f = new int[n + 1][m + 1];
        // for (int i = 0; i <= n; i ++) Arrays.fill(f[i],0x3f3f3f3f);
        for (int i = 1; i <= n; i ++) f[i][0] = i;
        for (int j = 1; j <= m; j ++) f[0][j] = j;
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= m; j ++) {
                f[i][j] = Math.min(f[i - 1][j],f[i][j - 1]) + 1;
                f[i][j] = Math.min(f[i][j],f[i - 1][j - 1] + (word1.charAt(i) == word2.charAt(j) ? 0 : 1));
            }
        }
        return f[n][m];
    }
}

为什么这里可以去掉初始化,因为我们更新最大值时没有用到它未更新时的状态,因此动态规划依然按照拓扑序

84、柱形图中最大的矩形

1、 此题的本质是找到每个柱形条左边和右边最近的比自己低的矩形条,然后用宽度乘上当前柱形条的高度作为备选答案。
2、解决此类问题的经典做法是单调栈,维护一个单调递增的栈,如果当前柱形条 i 的高度比栈顶要低,则栈顶元素 cur 出栈。出栈后,cur 右边第一个比它低的柱形条就是 i,左边第一个比它低的柱形条是当前栈中的 top。不断出栈直到栈为空或者柱形条 i 不再比 top 低。
3、满足 2 之后,当前矩形条 i 进栈。

class Solution {
    public int largestRectangleArea(int[] heights) {
        int n = heights.length;
        Stack<Integer> stk = new Stack<>();
        int[] l = new int[n];
        int[] r = new int[n];
        for (int i = 0; i < n; i ++) {
            while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) stk.pop();
            if (stk.isEmpty()) l[i] = -1;
            else l[i] = stk.peek();
            stk.push(i);
        }
        stk.clear();
        for (int i = n - 1; i >= 0; i --) {
            while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) stk.pop();
            if (stk.isEmpty()) r[i] = n;
            else r[i] = stk.peek();
            stk.push(i);
        }
        int res = 0;
        for (int i = 0; i < n; i ++) {
            res = Math.max(res,(r[i] - l[i] - 1) * heights[i]);
        }
        return res;
    }
}

85、最大矩形

 

(单调栈) O(nm)O(nm)
1、将 Largest Rectangle in Histogram 问题扩展到二维。
2、一行一行考虑,类比 Largest Rectangle in Histogram,一行内所有柱形条的高度 heights 就是当前 (i, j) 位置能往上延伸的最大高度。
3、直接套用 Largest Rectangle in Histogram 的单调栈算法即可。

class Solution {
    public int largestRectangleArea(int[] heights) {
        int n = heights.length;
        Stack<Integer> stk = new Stack<>();
        int[] l = new int[n];
        int[] r = new int[n];
        for (int i = 0; i < n; i ++) {
            while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) stk.pop();
            if (stk.isEmpty()) l[i] = -1;
            else l[i] = stk.peek();
            stk.push(i);
        }
        stk.clear();
        for (int i = n - 1; i >= 0; i --) {
            while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) stk.pop();
            if (stk.isEmpty()) r[i] = n;
            else r[i] = stk.peek();
            stk.push(i);
        }
        int res = 0;
        for (int i = 0; i < n; i ++) {
            res = Math.max(res,(r[i] - l[i] - 1) * heights[i]);
        }
        return res;
    }


    public int maximalRectangle(char[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;
        int[][] f = new int[n][m];
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < m; j ++) {
                if (matrix[i][j] == '1') {
                    if (i == 0) f[i][j] = 1;
                    else f[i][j] = 1 + f[i - 1][j];
                }
            }
        }
        int res = 0;
        for (int i = 0; i < n; i ++) res = Math.max(res,largestRectangleArea(f[i]));
        return res;
    }
}

 4721、排队

 

这道题是单调栈加二分的经典题目,以往的单调栈最常用是求我们最靠近且最小(大)的值,而本题中求的是;最远最小的值,因此我们要改变单调栈的添加顺序,从后往前,试想:如果存在一个靠左的数比靠右的数还大,那它是没有必要存在栈中的,因此栈中一定是从大到小的顺序,因此我们可以对每一个元素二分求小于它的数里边最大的一个

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] h = new int[n];
        for (int i = 0; i < n; i ++) h[i] = sc.nextInt();
        int top = 0;
        int[] stk = new int[n + 10];
        int[] res = new int[n];
        for (int i = n - 1; i >= 0; i --) {
            if (top == 0 || h[stk[top - 1]] >= h[i]) res[i] = -1;
            else {
                int l = 0;
                int r = top - 1;
                while (l < r) {
                    int mid = l + r >> 1;
                    if (h[stk[mid]] < h[i]) r = mid;
                    else l = mid + 1;
                }
                res[i] = stk[r] - i - 1;
            }
            if (top == 0 || h[i] < h[stk[top - 1]]) stk[top ++] = i;
        }
        for (int i = 0; i < n; i ++) {
            System.out.print(res[i] + " ");
        }
    }
}

 

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

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

相关文章

Spring Boot 入门

37) Boot 骨架项目 https://start.spring.io/pom.xml 38) Boot War项目 步骤1&#xff1a;创建模块&#xff0c;区别在于打包方式选择 war 步骤2&#xff1a;编写控制器 Controller public class MyController { ​RequestMapping("/hello")public String abc() …

南京溧水农民丰收节 国稻种芯·中国水稻节:江苏味稻文化

南京溧水农民丰收节 国稻种芯中国水稻节&#xff1a;江苏味稻文化 &#xff08;融媒体记者 诸婧雯&#xff09;新闻中国采编网 中国新闻采编网 谋定研究中国智库网 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff1a;由溧水区政府、市农业农村局主办…

MCE | Hippo 途径与靶向策略

在 PubMed 输入了“Hippo pathway or YAP/TAZ”&#xff0c;小编发现近十年来与 Hippo 通路沾点边的研究势头猛烈&#xff0c;且发的文章不少都“非富即贵”&#xff0c;如发表在 Nature Cell Biology 上的两篇关于 YAP (TAZ) 相变的文章 (两篇结论相反的文章&#xff0c;还能双…

红黑树C++实现

目录 一、红黑树的概念 二、红黑树的性质 三、红黑树节点的定义 四、红黑树的插入 4.1 插入节点 4.2 插入节点的颜色 4.3 调整情况1 4.4 调整情况2 4.5 调整情况3 4.6 调整情况总结 五、调整的实现 5.1 调整的步骤分析 5.2 代码实现 六、树的平衡判断 七、源代码…

微信小程序制作要多少钱?【制作小程序】

关于微信小程序制作要多少钱的问题&#xff0c;是很多企业商家在制作小程序之前需要了解的事项&#xff0c;因为总是听说制作小程序的费用有高有低&#xff0c;而他们又对这方面不太了解&#xff0c;所以也还是需要了解微信小程序制作要多少钱的。那么微信小程序制作要多少钱呢…

RocketMQ中生产者发消息前为啥一定要调用start()方法?

前言 我们在使用RocketMQ发送消息时&#xff0c;一般都会使用DefaultMQProducer&#xff0c;类型的代码如下&#xff1a; DefaultMQProducer producer new DefaultMQProducer("producer_group"); producer.setNamesrvAddr("42.192.50.8:9876"); try {pr…

Chrome 103支持使用本地字体,纯前端导出PDF优化

在前端导出PDF&#xff0c;解决中文乱码一直是一个头疼的问题。要解决这个问题&#xff0c;需要将ttf等字体文件内容注册到页面PDF生成器中。但是之前网页是没有权限直接获取客户机器字体文件&#xff0c;这时就需要从服务器下载字体文件或者提示用户选择字体文件上传到页面。对…

链接杂谈 CASPP

构建大型程序 构建大型程序&#xff0c;不可避免的一个问题是链接问题&#xff1a; - 链接器提示&#xff1a;缺少某个模块 缺少某个库 不兼容的库版本 理解全局变量的链接 你的代码可能有多个全局变量&#xff0c;有些是强变量&#xff0c;有些是弱定义&#xff0c;执行…

清除浮动的常用方法

关于浮动 我们为什么需要浮动&#xff1f; 我们想把多个块级元素放到同一行上。 打破标准流的限制。 浮动原来做图文混排效果&#xff0c;现在主要用来做网页布局的。 浮动语法 只有左浮动和右浮动。 float: left; float: right;浮动特点 1.浮动元素会脱离标准流&#x…

Win10禁止应用独占麦克风

痛点需求&#xff1a; qq和微信同时发起语音通话&#xff0c;发现只有一个qq说话对方能听到&#xff0c;但是微信却不能&#xff0c;这是典型的应用程序独占了麦克风&#xff0c;导致其他应用无法使用。 有没有办法让qq和微信同时使用麦克风呢&#xff1f; 答案是&#xff1a;有…

图的拓扑序列

拓扑序列&#xff1a; 拓扑序是按照点的先后顺序排列的。拓扑序列满足以下两点&#xff1a; 1.每个顶点在序列中出现且只出现一次。 2.若存在一条从顶点 A 到顶点 B 的路径&#xff0c;那么在序列中顶点 A 出现在顶点 B 的前面。 拓扑序列只存在于有向无环图中。可以理解成…

MCE | 肝炎病毒是如何诱发肝癌的

肝炎病毒分类 肝炎病毒是世界上最常见的肝炎病因&#xff0c;其它原因包括酗酒、某些药物、毒素、其他感染、自身免疫性疾病和非酒精性脂肪性肝炎 (NASH)。肝炎病毒共有五种主要的肝炎病毒株&#xff0c;分别为 A、B、C、D 和 E 型。目前&#xff0c;全世界大约有 3.25 亿人患…

2023中国绿色铝业国际峰会

会议背景 铝行业属于能源高度密集型行业&#xff0c;主要包括铝矿石开采、氧化铝生产、电解铝生产和铝材加工等环节。我国原铝产量自2001年以来一直占据世界首位&#xff0c;连续7年产量占比超过全球50%。然而与国际先进铝生产企业相比&#xff0c;我国铝生产企业单位原铝碳…

C# 自定义事件

一 自定义事件 例如&#xff0c;利用自定义绘制的技术&#xff0c;画出一个圆角按钮。 现在来看&#xff0c;怎么样给它添加自定义的事件。 二 要点与细节 1 Control 类本身就有继承的鼠标和键盘事件&#xff0c;这里只是一个引子&#xff0c;用于引出更复杂的自定义事件。 …

web测试——业务测试2

1.历史数据 前端&#xff1a; 组件相关  组件内部是否动过&#xff1b;  展示的数据是否受影响&#xff1b;  失焦后的校验(爆红) 页面样式相关  坐标位置、  按钮位置是否动过&#xff0c;  新版本上线对历史配置的影响 交互提示相关  新手引导的展示位置、关闭后的展…

pycharm2022.2 远程连接服务器调试代码

目的&#xff1a; 同步本地和服务器的全部或者部分文件本地debug&#xff0c;服务器跑实验 需要条件&#xff1a; 服务器上已经创建好虚拟环境你本地已经安装好pycharm 1.1 File → Settings → Project:XXX →Python Interpreter 打开之后再右边这添加解释器。选On SSH 1.2把…

简单的网页制作期末作业——电影泰坦尼克号(4页)

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 文章目录一、网页介绍一…

小学生python游戏编程arcade----excel调用

小学生python游戏编程arcade----excel调用前言小学生python游戏编程arcade----excel调用1、excel文件1.1 excel表头1.2 excel文件1.3 文件读取函数1.4 打开excel文件读取数据,每行一个字典&#xff0c;再总存为序列1.5 打开excel文件读取数据&#xff0c;取两列存为字典1.6 游戏…

[漏洞复现] jenkins 远程代码执行 (CVE-2019-100300)

文章目录一、简介二、影响版本三、复现四、修复一、简介 拥有Overall/Read 权限的用户可以绕过沙盒保护&#xff0c;在jenkins可以执行任意代码。此漏洞需要一个账号密码和一个存在的job。 Jenkins的pipeline主要是通过一个配置文件或者job里面的pipeline脚本配置来设定每个j…

锐捷MPLS跨域方案C2实验配置

目录 配置ASBR之间的EBGP邻居 配置PE之间的Vpnv4邻居 此时配置PE与CE设备对接命令 手工配置为PE地址分配标签 MPLS隧道——跨域解决方案C1、C2讲解_静下心来敲木鱼的博客-CSDN博客https://blog.csdn.net/m0_49864110/article/details/127634890?ops_request_misc%257B%252…