动态规划设计LeetCode 300. 最长递增子序列 354. 俄罗斯套娃信封问题

news2024/11/18 2:48:53

🌈🌈😄😄

欢迎来到茶色岛独家岛屿,本期将为大家揭晓LeetCode 300. 最长递增子序列  354. 俄罗斯套娃信封问题,做好准备了么,那么开始吧。

🌲🌲🐴🐴

动态规划

  • 首先,动态规划问题的一般形式就是求最值
  • 求解动态规划的核心问题是穷举
  • 动态规划的核心思想就是穷举求最值。
  • 明确 base case -> 明确「状态」-> 明确「选择」 -> 定义 dp 数组/函数的含义

框架:

# 自顶向下递归的动态规划
def dp(状态1, 状态2, ...):
    for 选择 in 所有可能的选择:
        # 此时的状态已经因为做了选择而改变
        result = 求最值(result, dp(状态1, 状态2, ...))
    return result

# 自底向上迭代的动态规划
# 初始化 base case
dp[0][0][...] = base case
# 进行状态转移
for 状态1 in 状态1的所有取值:
    for 状态2 in 状态2的所有取值:
        for ...
             for 选择1 in 选择1的所有取值:
                 for 选择2 in 选择2的所有取值:
                       排除不合法选择
                        if()continue;
  
                        dp[状态1][状态2][...] = 求最值(选择1,选择2...)
结束条件
return ...

知道了这是个动态规划问题,思考如何列出正确的状态转移方程?

1、确定 base case

2、确定「状态」,也就是原问题和子问题中会变化的变量

3、确定「选择」,也就是导致「状态」产生变化的行为

4、明确 dp 函数/数组的定义

300. 最长递增子序列

一、力扣示例

300. 最长递增子序列 - 力扣(LeetCode)icon-default.png?t=N0U7https://leetcode.cn/problems/longest-increasing-subsequence/

二、解决办法

方法一:动态规划

1、确定 base case

int[] dp = new int[nums.length];
// base case:dp 数组全都初始化为 1
Arrays.fill(dp, 1);

2、确定「状态」,也就是原问题和子问题中会变化的变量。dp[i]

3、确定「选择」,也就是导致「状态」产生变化的行为。dp[j],遍历小于i之前的dp[j],求最大dp[j],再加一得dp[i]

4、明确 dp 函数/数组的定义。dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列的长度

class Solution {
    public int lengthOfLIS(int[] nums) {
        // dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列的长度
        int[] dp = new int[nums.length];
        // base case:dp 数组全都初始化为 1
        Arrays.fill(dp, 1);
        //自底向上
        for (int i = 0; i < nums.length; i++)//状态,变量为dp[i]       
        {
            for (int j = 0; j < i; j++) //选择,产生变化的行为是dp[j]           
            {
                if (nums[i] > nums[j])
                    dp[i] = Math.max(dp[i], dp[j] + 1);
            }
        }
        int res = 0;
        for (int i = 0; i < dp.length; i++) {
            res = Math.max(res, dp[i]);
        }
        return res;
    }
}

这个解法不是最优的,可能无法通过所有测试用例 

方法二:二分查找,此方法更高效,通过所有测试用例

这个解法的时间复杂度为 O(NlogN)

首先定义了一个数组 top,用来存储当前已经处理好的 LIS 的顶部,即存储每一堆牌的最高牌。

对于输入数组的每一个元素,都将其看作一张要处理的扑克牌。

接着,开始进行二分查找,以找到一个合适的牌堆,使得当前这张牌能够放入。在查找过程中,如果当前的牌堆顶的牌比要处理的扑克牌高,那么搜索区间的右端点变为中间位置;如果当前的牌堆顶的牌比要处理的扑克牌低,那么搜索区间的左端点变为中间位置加 1;如果当前的牌堆顶的牌和要处理的扑克牌相等,那么右端点也变为中间位置。

最后,如果没有找到合适的牌堆,就需要新建一堆。否则,将当前这张牌放入找到的牌堆顶。

完成对所有元素的处理后,牌堆数即为最长上升子序列的长度,最后通过返回 piles 的值来表示 LIS 的长度。

总的来说就是不断遍历数组元素通过二分查找找到每个元素位置,然后计算能有几堆(piles 长度)为最长上升子序列的长度。

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] top = new int[nums.length];
        // 牌堆数初始化为 0
        int piles = 0;
        for (int i = 0; i < nums.length; i++) {
            // 要处理的扑克牌
            int poker = nums[i];

            /***** 搜索左侧边界的二分查找 *****/
            int left = 0, right = piles;
            while (left < right) {
                int mid = (left + right) / 2;
                if (top[mid] > poker) {
                    right = mid;
                } else if (top[mid] < poker) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            /*********************************/
            
            // 没找到合适的牌堆,新建一堆
            if (left == piles) piles++;
            // 把这张牌放到牌堆顶
            top[left] = poker;
        }
        // 牌堆数就是 LIS 长度
        return piles;
    }
}

 354. 俄罗斯套娃信封问题

一、力扣示例

354. 俄罗斯套娃信封问题 - 力扣(LeetCode)icon-default.png?t=N0U7https://leetcode.cn/problems/russian-doll-envelopes/

二、解决办法

这道题目其实是最长递增子序列的一个变种,相当于在二维平面中找一个最长递增的子序列,其长度就是最多能嵌套的信封个数

二分查找

解法:先对宽度 w 进行升序排序,如果遇到 w 相同的情况,则按照高度 h 降序排序;之后把所有的 h 作为一个数组,在这个数组上计算 LIS 的长度就是答案

 

class Solution {
    public int maxEnvelopes(int[][] envelopes) {
        int n = envelopes.length;
        // 按宽度升序排列,如果宽度一样,则按高度降序排列
        Arrays.sort(envelopes, new Comparator<int[]>() 
        {
            public int compare(int[] a, int[] b) {
                return a[0] == b[0] ? 
                    b[1] - a[1] : a[0] - b[0];
            }
        });
        // 对高度数组寻找 LIS
        int[] height = new int[n];
        for (int i = 0; i < n; i++)
            height[i] = envelopes[i][1];

        return lengthOfLIS(height);
    }
    int lengthOfLIS(int[] nums) {
        int[] top = new int[nums.length];
        // 牌堆数初始化为 0
        int piles = 0;
        for (int i = 0; i < nums.length; i++) {
            // 要处理的扑克牌
            int poker = nums[i];

            /***** 搜索左侧边界的二分查找 *****/
            int left = 0, right = piles;
            while (left < right) {
                int mid = (left + right) / 2;
                if (top[mid] > poker) {
                    right = mid;
                } else if (top[mid] < poker) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }                       
            // 没找到合适的牌堆,新建一堆
            if (left == piles) piles++;
            // 把这张牌放到牌堆顶
            top[left] = poker;
        }
        // 牌堆数就是 LIS 长度
        return piles;
    }
}

 

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

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

相关文章

【openGauss】把应用开发中的设置客户端字符编码往细了说

前言 早前写过两篇有关Oracle字符集的文章 【ORACLE】谈一谈Oracle数据库使用的字符集,不仅仅是乱码 【ORACLE】谈一谈NVARCHAR2、NCHAR、NCLOB等数据类型和国家字符集 基本说明了 ”数据字符编码“、”客户端字符编码“、”数据库字符编码“三者的关系&#xff0c;这些关系&a…

磨金石教育摄影技能干货分享|年味就是幸福圆满的味道

时光荏苒&#xff0c;时代变迁。以前是古街古巷&#xff0c;现在是高楼大厦。以前的老街&#xff0c;灯笼满街&#xff0c;烟火气十足。现在的城市商业街中霓虹灯可以展示出各种新年的影像。无论时代如何变迁&#xff0c;无论时光走了多远&#xff0c;我们对春节的期待从未改变…

吴恩达机器学习(二)——机器学习之监督模型之回归模型之线性回归模型

y-hat一般指的就是预测值 线性回归模型实例 构建模型 我们有一个房子的大小size&#xff0c;得到房屋价格&#xff08;price&#xff09;&#xff0c;通过这两个常数就可计算一个输入和输出的函数关系。 f w&#xff0c;b(x(i)) wx(i) b i指的是第几个训练数据 评估模型——…

【教程】browsermob-proxy 基于Java的代理服务 配合selenium使用

【教程】browsermob-proxy 基于Java的代理服务 配合selenium使用 配置依赖 <!-- 代理 配合 selenium进行抓包修改等 --><dependency><groupId>net.lightbody.bmp</groupId><artifactId>browsermob-core</artifactId><version>2.1.5&…

H3C Switch S1848G端口限速

需求&#xff1a;在交换机层面对接入用户的网络流量限速1.交换机信息2.主机限速前2.1本机IP和MAC信息依次打开控制面板\所有控制面板项\网络连接2.2限速前测速使用浏览器打开https://10000.gd.cn/测速3.主机限速后3.1查看主机所在交换机接口点击“网络”-“MAC地址”&#xff0…

【微信小程序】给你的页面加上一个填写进度表

前言在搭建一些与申请相关的微信小程序的时候&#xff0c;用户会遇到需要填写很多表单的情况&#xff0c;面对未知的表单数量&#xff0c;用户往往就会放弃填写申请表格。在此基础上作为开发者的我们常常会收到这样的一个任务——给申请页面加上一个填写进度表。这样不仅可以优…

274. H 指数

274. H 指数一、题目描述二、题目分析三、解题思路3.1 更换H指数定义3.2 二分法枚举H指数一、题目描述 二、题目分析 这道题比较绕&#xff0c;理解题目意思&#xff0c;根据题目的说法&#xff0c;所谓的H指数就是&#xff1a;总共有 h 篇论文分别被引用了至少 h 次。且其余的…

二战阿里巴巴成功上岸,准备了小半年,要个28k应该也算不上很高吧~

先说下我基本情况&#xff0c;本科不是计算机专业&#xff0c;现在是学通信&#xff0c;然后做图像处理&#xff0c;可能面试官看我不是科班出身没有问太多计算机相关的问题&#xff0c;因为第一次找工作&#xff0c;阿里的游戏专场又是最早开始的&#xff0c;就投递了&#xf…

Spring Cloud Alibaba系列三:集成Gateway实现路由管理

文章目录Spring Cloud Alibaba系列三&#xff1a;集成Gateway实现路由管理前言1、改造父项目 pom 文件2、创建 gateway 子 module3、配置yml文件Spring Cloud Alibaba系列三&#xff1a;集成Gateway实现路由管理 spring cloud alibaba 版本对照 spring cloud alibaba 有严格的…

【MPP数据库】TiDB表分区探索与实践

方案背景——为什么要进行分区&#xff1f; 一是老板通Tidb集群每天涉及50张表、2亿多条数据回流&#xff0c;合理使用Hash可以把写入压力打散到不同的TiKV&#xff1b; 二是对于大集团数据做聚合&#xff0c;利用分区裁剪原理&#xff0c;查询时可以充当前置索引&#xff0c…

1月第4周榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年1月23日-1月29日飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B…

卫星地图——MAP(c++)

卫星地图 题目描述 一张矩形的卫星地图&#xff0c;有M行N列。行列中的0表示空地&#xff0c;1表示有建筑。有3种类型的建筑: L型: 仅在一行上占据连续的若干个格子&#xff0c;长度至少为2&#xff0c;至多为N C型&#xff1a;仅在一列上占据连续的若干个格子&#xff0c;…

春节机票销售大增!航空领域哪些业务风险要注意?

目录 航空领域常见的业务风险 2022年航空业务风险趋势分析 航空领域业务风险欺诈分析 如何防范航空业务风险 针对恶意网络爬虫 针对仿冒登录与内控风险 安全技术 春节旅游与出行数据陆续出炉。中国民航局数据显示&#xff0c;2023年1月21日至27日&#xff08;农历除夕至…

Linux - Linux系统

一、Linux系统Linux&#xff0c;全称GNU/Linux。Linux是一个开源、免费的操作系统&#xff0c;其稳定性、安全性、处理多并发能力已经得到业界的认可&#xff0c;目前大多数企业级应用甚至是集群项目都部署运行在linux操作系统之上&#xff0c;很多软件公司考虑到开发成本都首选…

CnOpenData中国核酸检测机构及采样点数据

一、数据简介 2020年1月21日&#xff0c;国家卫健委发布1号公告&#xff0c;将新型冠状病毒感染的肺炎纳入《中华人民共和国传染病防治法》规定的乙类传染病&#xff0c;并采取甲类传染病的预防、控制措施。目前&#xff0c;新型冠状病毒肺炎防控仍处于关键阶段&#xff0c;核酸…

ThinkPHP6 文件上传

内置文件上传使用\think\facade\Filesystem类封装方法 目录 简单上传 public存储文件 文件验证 命名规则 使用sha1 使用MD5 使用date 指定文件名称 自定义命名规则 更多上传设置 总结 简单上传 直接上传&#xff0c;使用默认上传设置 $savename \think\facade\F…

业务平台扩展支持TDengine时序数据库方案

1 场景与架构 1.1业务架构 这里涉及项目隐私&#xff0c;架构图不方便公开。 大致情况就是&#xff1a; 应用层的园区畅行、生态宜居、安全守护是我方要交付的系统。 平台层的物联网感知中台是我方平台。 1.2数据架构 从数据架构看&#xff0c;园区畅行…

第四章 git分支操作

4.1什么是分支 在版本控制过程中&#xff0c;同时推进多个任务&#xff0c;为每个任务&#xff0c;我们就可以创建每个任务的单独 分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来&#xff0c;开发自己分支的时 候&#xff0c;不会影响主线分支的运行。对于初…

优化器-RBO 的规则转化

一、RBO 背景介绍RBO&#xff08;Rule-Based Optimization&#xff0c;基于规则的优化器&#xff09;有着一套严格的使用规则&#xff0c;按照 RBO 去写 SQL 语句&#xff0c;无论数据表中的内容怎样&#xff0c;也不会影响到你的“执行计划”。换言之 RBO 对数据不“敏感”&am…

码元,码元速率,波特率,比特率(个人理解总结)

参考&#xff1a;https://baike.baidu.com/item/%E7%A0%81%E5%85%83%E4%BC%A0%E8%BE%93%E9%80%9F%E7%8E%87/6305673 https://baike.baidu.com/item/%E7%A0%81%E5%85%83%E9%80%9F%E7%8E%87/10945076 https://baike.baidu.com/item/%E6%9B%BC%E5%BD%BB%E6%96%AF%E7%89%B9%E7%BC%9…