贪心+动归1

​​​​​​​​​​​​​​跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

class Solution {public boolean canJump(int[] nums) {// 跳跃覆盖范围究竟可不可以覆盖到终点!// 直接取最大值,总和大于nums.length即可if (nums.length == 1) {return true;}// 覆盖范围, 初始覆盖范围应该是0,因为下面的迭代是从下标0开始的int cover = 0;// 在覆盖范围内更新最大的覆盖范围 因此是i<=coverfor (int i = 0; i <= cover; i++) {cover = Math.max(cover, i + nums[i]); // 直接在当前下标加上能跳的最大范围if (cover >= nums.length - 1) {return true;}}return false;}
}

跳跃游戏 II

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。

class Solution {public int jump(int[] nums) {//要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!//在数组末端时,不需要跳转 步数为0if (nums == null || nums.length == 0 || nums.length == 1) {return 0;}//需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。//记录跳跃的次数int count = 0;//当前的覆盖最大区域int curDistance = 0;//最大的覆盖区域int maxDistance = 0;for (int i = 0; i < nums.length; i++) {//在可覆盖区域内更新最大的覆盖区域maxDistance = Math.max(maxDistance, i + nums[i]);//说明当前一步,再跳一步就到达了末尾if (maxDistance >= nums.length - 1) {count++;break;}//走到当前覆盖的最大区域时,更新下一步可达的最大区域if (i == curDistance) {curDistance = maxDistance;count++;}}return count;}
}

划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表。

edge[chars[i] - 'a'] = i; 找到i对应位置 找到i对应位置 例如:字母c edge[2]=i;进行更新,找到最后位置

class Solution {public List<Integer> partitionLabels(String s) {//如何统计相同字母出现的最大下标:统计次数//1.统计每一个字符最后出现的位置//2.从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点List<Integer> list = new LinkedList<>();int[] edge = new int[27];char[] chars = s.toCharArray();//1.统计每一个字符最后出现的位置for (int i = 0; i < chars.length; i++) {edge[chars[i] - 'a'] = i;  //eg.  字母c edge[2]=i;进行更新,找到最后位置}//2.从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点int left = 0;//为什么取-1int right = 0;for (int i = 0; i < chars.length; i++) {right = Math.max(right, edge[chars[i] - 'a']);//获取字符最远处下标if (i == right) {list.add(right - left + 1);//统计本次符合条件个数left = i + 1;}}return list;}
}

无重叠区间

重叠区间问题

给定一个区间的集合 intervals ,其中 intervals[i] = [start(i), end(i)] 。返回 需要移除区间的最小数量,使剩余区间互不重叠

class Solution {public int eraseOverlapIntervals(int[][] intervals) {/*重叠区间问题//1.按照左区间或是右区间进行排序//2.比较intervals[i][0]和interval[i-1][1](左边界和右边界)//3.更新最小右边界//根据题目要求:合并 、删除 。。。*///1.按照左区间或是右区间进行排序Arrays.sort(intervals, (a, b) -> {//升序排列return Integer.compare(a[0], b[0]);});//2.比较intervals[i][0]和interval[i-1][1](左边界和右边界)int remove = 0;//需要移除的区间数。int pre = intervals[0][1];//初始化为第一个区间的结束位置 intervals[0][1]。for (int i = 1; i < intervals.length; i++) {//3.更新最小右边界 上一个区间右边界与下一个区间左边界比较if (pre > intervals[i][0]) {//检查当前区间的起始位置 intervals[i][0] 是否小于前一个区间的结束位置 pre。remove++;pre = Math.min(pre, intervals[i][1]);//更新 pre 为当前区间结束位置 intervals[i][1] 和 pre 的较小值,以确保下一个区间的起始位置不小于 pre。} else {pre = intervals[i][1];}}return remove;}
}

动态规划(重叠子问题)

动态规划问题的一般形式就是求最值。比如说让你求最长递增子序列呀,最小编辑距离呀等等。

如果某一问题有很多重叠子问题,使用动态规划是最有效的。动态规划中每一个状态一定是由上一个状态推导出来的。

动规是由前一个状态推导出来的,而贪心是局部直接选最优的。

明确 base case -> 明确「状态」-> 明确「选择」 -> 定义 dp 数组/函数的含义。

重叠子问题、最优子结构、状态转移方程就是动态规划三要素

递归算法的时间复杂度怎么计算?就是用子问题个数乘以解决一个子问题需要的时间

动态规划的解题步骤

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化 (递推公式决定了dp数组要如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

斐波那契数

「自底向上」的思路:直接从最底下、最简单、问题规模最小、已知结果的 f(1) 和 f(2)(base case)开始往上推,直到推到我们想要的答案 f(20)。这就是「递推」的思路,这也是动态规划一般都脱离了递归,而是由循环迭代完成计算的原因。

class Solution {public int fib(int n) {if(n<=1){return n;}//dp[i]的定义为:第i个数的斐波那契数值是dp[i]int[]dp=new int[n+1];dp[0]=0;dp[1]=1;for(int i=2;i<=n;i++){dp[i]=dp[i-1]+dp[i-2];}return dp[n];}
}

70 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

class Solution {public int climbStairs(int n) {//dp[i]: 爬到第i层楼梯,有dp[i]种方法int[] dp = new int[n + 1];  //为了存储第0层到第n层的结果 数组长度是n+1
0       dp[0]=1;dp[1]=1;for(int i=2;i<=n;i++){dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}

使用最小花费爬楼梯

class Solution {public int minCostClimbingStairs(int[] cost) {//dp[i]的定义:到达第i台阶所花费的最少体力为dp[i]。int[] dp = new int[cost.length+1];//前两台阶不费力dp[0] = 0;dp[1] = 0;//最小花费,递推公式和花费联系上for(int i=2;i<=cost.length;i++){dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);}return dp[cost.length];}}

118 杨辉三角

给定一个非负整数 numRows生成「杨辉三角」的前 numRows行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

class Solution {public List<List<Integer>> generate(int numRows) {// 结果集合List<List<Integer>> res = new ArrayList<>();// 行for (int i = 0; i < numRows; i++) {// 每一行List<Integer> list = new ArrayList<>();// 行数等于列数int row = i + 1; //列数for (int j = 0; j < row; j++) {//如果当前列是第一列或最后一列,则将 1 添加到当前行的列表中if (j == 0 || j == row - 1) {list.add(1);} else {//否则,使用上一行的第 j 列和第 j-1 列的值相加,将结果添加到当前行的列表中。//获取上一行数据List<Integer> pre = res.get(i - 1);int num = pre.get(j) + pre.get(j - 1);list.add(num);}}res.add(list);}return res;}
}

背包问题

背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。

要注意题目描述中商品是不是可以重复放入。

一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,写法还是不一样的。

问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]); ,对应题目如下:
416.分割等和子集 (物品正序,背包倒序)

给你一个 只包含正整数 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。


这道题目就是一道01背包应用类的题目,需要我们拆解题目,然后套入01背包的场景。

01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。

class Solution {public boolean canPartition(int[] nums) {/*** 1. 确定dp数组及下标含义 :容量为j的背包,所背的物品价值最大可以为dp[j],背包价值等于总和的一半* 2. 递推公式 dp[j]=Math.max(dp[j],dp(j-nums[i])+nums[i])* 3. 初始化 dp[0]=0 非零dp[]:0 只包含正整数的非空数组,所以非0下标的元素初始化为0* 4. 遍历顺序 dp[j] 如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历!* 5. 推导结果*/if (nums == null || nums.length == 0) {return false;}int sum = 0;for (int num : nums) {sum += num;}//总和为奇数不能平分if (sum % 2 != 0) {return false;}int target = sum / 2;int[] dp = new int[target + 1];for (int i = 0; i < nums.length; i++) {//物品for (int j = target; j >= nums[i]; j--) {//背包 倒序遍历dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);}//剪枝一下,每一次完成for-loop,立即检查是否dp[target] == targetif (dp[target] == target) {return true;}}return dp[target] == target;}
}
  • 动态规划:1049.最后一块石头的重量 II(opens new window)
问装满背包有几种方法:dp[j] += dp[j - nums[i]] ,对应题目如下:
  • 动态规划:494.目标和(opens new window)
518. 零钱兑换 II(opens new window)

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。

请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。

假设每一种面额的硬币有无限个。


/*** 先物品后背包的情况下,根据递推公式,dp【j】一定是来自于外层上一次的结果,而外层上一次的结果一定是来源于上一个物品的dp数组,所以不会出现物品2在物品1之前的情况,也就是只会出现【物品1,物品1,物品2】这种情况,而物品2不会出现在物品1之前,(不会重复)恰好对应组合问题;* 而外层遍历背包 内层遍历物品就不一样了,每一层的dp【j】都是在固定j的情况下,把物品从头开始遍历,所以dp【j】来自于上一层的结果,而上一层的结果又遍历了所有物品,所以这种遍历方式会出现【物品1,物品2,物品1】这种情况,恰好对应了排列问题* 组合不强调元素之间的顺序,排列强调元素之间的顺序。* * 1.dp[j]:凑成总金额j的货币组合数为dp[j]* 2.dp[j] 就是所有的dp[j - coins[i]](考虑coins[i]的情况)相加。* dp[j] += dp[j - coins[i]];* 3.初始化  dp[0] = 1 下标非0的dp[j]初始化为0,这样累计加dp[j - coins[i]]的时候才不会影响真正的dp[j]* 4.遍历顺序 先物品后背包* 如果求组合数就是外层for循环遍历物品,内层for遍历背包。* 如果求排列数就是外层for遍历背包,内层for循环遍历物品。*/
class Solution {public int change(int amount, int[] coins) {int[] dp = new int[amount + 1];dp[0]=1;//判断条件决定遍历的背包还是物体  求的是组合数for (int i = 0; i <coins.length; i++) {//物品   for (int j = coins[i]; j <=amount ; j++) {//背包  价值到背包dp[j]+=dp[j-coins[i]];}}return dp[amount];}
}

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

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

相关文章

Claude3.5:编码螃蟹游戏就是这么轻松

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则…

【错误记录】Android 应用漏洞修复处理 ( 动态反调试漏洞 | 调用 Debug.isDebuggerConnected 函数查询是否被动态调试 )

文章目录 一、动态调试攻击二、Frida、Xposed 动态调试攻击应对措施三、调用 Debug.isDebuggerConnected 函数查询是否被动态调试 一、动态调试攻击 针对 Android 应用 进行 动态调试攻击 , 攻击者利用 Frida、Xposed 等调试工具 , 对 Android 应用进行 运行时 分析和修改 , 从…

UbuntuServer 22.04.4安装Docker

文章目录 一、docker安装二、docker基本命令用法三、docker命令示范 一、docker安装 1.sudo apt update ---更新软件包索引 2.sudo apt install ca-certificates curl gnupg lsb-release ---允许APT使用HTTPS 3.curl -fsSL https://download.docker.com/linux/ubuntu/gpg | su…

爱眼小妙招:台灯怎么选?学生如何正确使用台灯?

视力是心灵的窗户&#xff0c;尤其对于儿童来说更为重要。然而&#xff0c;随着现代生活方式的改变&#xff0c;孩子们面临越来越多的视力挑战。据统计&#xff0c;在近视学生中&#xff0c;近10%的人患有高度近视&#xff0c;而这一比例随年级的增加而逐渐上升。从幼儿园的小小…

【备忘录】配置 Docker 守护程序以使用代理服务器

配置/etc/docker/daemon.json Docker 守护程序在其启动环境中使用以下环境变量来配置 HTTP 或 HTTPS 代理行为&#xff1a; HTTP_PROXYhttp_proxyHTTPS_PROXYhttps_proxyNO_PROXYno_proxy 在 Docker Engine 23.0 及更高版本中&#xff0c;您还可以在/etc/docker/daemon.json…

电子杂志制作工具推荐:让你轻松成为编辑大人

在这个数字化的时代&#xff0c;电子杂志已经成为信息传播的重要载体。它不仅能够满足人们对阅读的需求&#xff0c;还能够提供更加丰富、互动的阅读体验。因此&#xff0c;掌握一款好用的电子杂志制作工具&#xff0c;已经成为每个编辑大人的必备技能。接下来告诉大家一个超简…

设置浏览器互不干扰

目录 一、查看浏览器文件路径 二、 其他盘新建文件夹Cache 三、以管理员运行CMD 四、执行命令 一、查看浏览器文件路径 chrome://version/ 二、 其他盘新建文件夹Cache D:\chrome\Cache 三、以管理员运行CMD 四、执行命令 Mklink /d "C:\Users\Lenovo\AppData\Loca…

【自动驾驶】从零开始做自动驾驶小车

文章目录 自动驾驶小车系统、运动底盘的运动学分析和串口通信控制电机PID控制IMU初始化与陀螺仪零点漂移ubuntu基础教程ROS基础键盘控制巡线(雷达避障)雷达跟随视觉跟踪2D建图、2D导航3D建图、3D导航纯视觉建图导航语音控制KCF跟随自主建图建图与导航多机编队WEB浏览器显示摄像…

计算机系统基础(一)

1. 引入——从源程序到可执行文件 了解高级语言编写的代码在后台是如何被编译并运行的 首先我们会编写一段代码&#xff0c;例如 #include<stdio.h>int main(){printf("hello world!\n");return 0; } 并把它命名为hello.c文件 预处理阶段 接下来通过命令…

2024.06.09校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、自动驾驶一周资讯 - 奔驰被曝将采用 Momenta 轻图城区方案&#xff1b;“蔚小理”2024年Q1财报&#xff1a;蔚来亏损是小鹏4倍 自动驾驶一周资讯 - 奔驰被曝将采用 Momenta 轻图城区方…

WPF/C#:在DataGrid中显示选择框

前言 在使用WPF的过程中可能会经常遇到在DataGrid的最前或者最后添加一列选择框的需求&#xff0c;今天跟大家分享一下&#xff0c;在自己的项目中是如何实现的。 整体实现效果如下&#xff1a; 如果对此感兴趣&#xff0c;可以接下来看具体实现部分。 实践 假设数据库中的…

【AI开放式讨论】-AI时代的个人该何去何从

当前AI通用模型都是大厂在进行训练&#xff0c;由于成本、数据等问题&#xff0c;个人也无法入局大模型的通用模型的开发中&#xff0c;个人只能针对大厂开源出的大模型产品进行使用&#xff0c;有一些技术能力的则可对大模型进行微调&#xff0c;或者进行垂直领域的训练生成专…

掌握PHP PDO:数据库世界的魔法师

介绍 1.1 什么是PDO&#xff1f; PDO&#xff08;PHP数据对象&#xff09;是PHP的一个轻量级数据库访问抽象层&#xff0c;允许开发者以一种统一的方式访问多种不同类型的数据库&#xff0c;如MySQL、PostgreSQL、SQLite等。它提供了一组类和方法&#xff0c;使得在PHP应用程…

【EndNote】EndNote进行文献管理可能遇到的问题和解决方案

一、安装GB/T7714-2015(numberic)文献style windows&#xff1a;https://blog.csdn.net/qq_36235935/article/details/115629694 mac os&#xff1a;Mac版Endnote 20导入中文参考格式Chinese Std GBT7714 (numeric)-CSDN博客 安装完之后需要调整Author Name格式&#xff1a;…

Python文件与面向对象知识点

目录 文件的基本概念 文件的读取 文件的追加 文件的写入 with语句 知识总结 面向对象的基本概念 类和实例 对象的属性和方法 类属性与方法 面向对象的三大特性 知识总结 文件的基本概念 文件的读取 文件的追加 文件的写入 with语句 知识总结 面向对象的基本概念 …

docker拉取镜像一直在加载中,且会提示error pulling image configuration

1、增加国内镜像配置 #查看文件内容 sudo vim /etc/docker/daemon.json如果没有该文件&#xff0c;则需要在/etc/docker中创建一个daemon.json 文件 创建文件 vim daemon.json#文件中添加以下json {"registry-mirrors":["https://docker.mirrors.ustc.edu.cn/…

第六十六天打卡 | 卡码网101 孤岛的总面积、卡码网102 沉没孤岛、卡码网103 水流问题、卡码网104 建造最大岛屿

卡码网101 孤岛的总面积 这一题在昨天的基础上&#xff0c;将比较得出最大孤岛面积的逻辑改为统计所有孤岛面积之和的逻辑即可。 最近做项目的时候也发现&#xff0c;很多时候代码逻辑能够复用最好就不要再自己写&#xff0c;防止出错&#xff0c;当然刷代码题的时候不…

webpack总结16--webpack入门学习

总结 通过前面的内容我们学会了 Webpack 基本使用&#xff0c;掌握了以下功能&#xff1a; 1.两种开发模式 开发模式&#xff1a;代码能编译自动化运行生产模式&#xff1a;代码编译优化输出 2.Webpack 基本功能 开发模式&#xff1a;可以编译 ES Module 语法生产模式&#…

V4L2读取摄像头资源

1.V4L2 它是Linux内核中标准的关于视频驱动程序&#xff0c;Video for Linux 2&#xff0c;简称V4L2。 它为Linux下的视频驱动提供了统一的接口&#xff0c;使得应用程序可以使用统一的API操作不同的视频设备。 V4L2支持三类设备&#xff1a;视频输入输出设备、VBI设备和rad…

MongoDB的Go语言操作示例总结

目录 前提条件 连接到MongoDB 简单示例 插入文档 查询文档 查询单个文档 查询多个文档 更新文档 更新单个文档 更新多个文档 删除文档 删除单个文档 删除多个文档 聚合管道 常见聚合操作符 $match $group $project $sort $limit $skip $lookup $unwind …