【Leetcode】最长递增子序列问题及应用

article/2025/9/21 0:14:40

文章目录

      • 最长递增子序列问题及应用
        • 300. 最长递增子序列
        • 面试题 17.08. 马戏团人塔
        • 354. 俄罗斯套娃信封问题
        • 面试题 08.13. 堆箱子
        • 1691. 堆叠长方体的最大高度
        • 406. 根据身高重建队列

最长递增子序列问题及应用

300. 最长递增子序列

请参考 【Leetcode】计算最长系列(动态规划) 中对 300. 最长递增子序列 的讲解。解题方法主要有两种:动态规划、贪心+二分查找

面试题 17.08. 马戏团人塔

1.题目描述

leetcode链接:面试题 17.08. 马戏团人塔
在这里插入图片描述

2.思路分析

题目要求在2个维度上(即身高 + 体重)同时保持严格递增。

那么我们可以先将其中一个维度排好序,以保证在一个维度上保持递增(此时并非严格递增);之后就可以专注于处理另一个维度。

先对身高体重排序,身高升序排列,身高相同,体重降序排列,这里可以使用二维数组的lambda表达式写法。可以参考:Java数组、ArrayList、HashMap排序总结。

之后就是计算最长递增子序列。身高已经按升序了,只需要判断体重。处理体重的问题就是处理最长递增子序列的问题。

参考最长递增子序列的解法。

3.参考代码

方法一:动态规划(超时)

class Solution {public int bestSeqAtIndex(int[] height, int[] weight) {int n = height.length;int[][] person = new int[n][2];for (int i = 0; i < n; i++) {person[i] = new int[]{height[i], weight[i]};}// 身高相同,体重降序Arrays.sort(person, (o1, o2) -> o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0]);int[] dp = new int[n];Arrays.fill(dp, 1);int res = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < i; j++) {if (person[i][1] > person[j][1]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}res = Math.max(dp[i], res); }return res;}
}

方法二:贪心 + 二分查找

class Solution {public int bestSeqAtIndex(int[] height, int[] weight) {int n = height.length;int[][] person = new int[n][2];for (int i = 0; i < n; i++) {person[i] = new int[]{height[i], weight[i]};}// 身高相同,体重降序Arrays.sort(person, (o1, o2) -> o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0]);int[] dp = new int[n];Arrays.fill(dp, 1);int res = 0;for (int[] per : person) {int left = 0, right = res;while (left < right) {int mid = (right - left) / 2 + left;if (dp[mid] < per[1]) {  // 要找的是dp数组中第一个小于当前h的位置left = mid + 1;} else {right = mid;}}dp[left] = per[1];if (res == left) res++;}return res;}
}

二分查找可以直接调API:

通过二分法在已经排好序的数组中查找指定的元素,并返回该元素的下标。

  1. 如果数组中存在该元素,则会返回该元素在数组中的下标
  2. 如果数组中不存在该元素,则会返回 -(插入点 + 1)
int res1 = Arrays.binarySearch(int[] arr, int key);  // 默认搜索整个数组
int res2 = Arrays.binarySearch(int[] arr, int fromIndex, int toIndex, int key);  // 搜索数组指定索引内
class Solution {public int bestSeqAtIndex(int[] height, int[] weight) {int n = height.length;int[][] person = new int[n][2];for (int i = 0; i < n; i++) {person[i] = new int[]{height[i], weight[i]};}// 身高相同,体重降序Arrays.sort(person, (o1, o2) -> o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0]);int[] dp = new int[n];Arrays.fill(dp, 1);int res = 0;for (int[] per : person) {int i = Arrays.binarySearch(dp, 0, res, per[1]);if (i < 0) i = -(i + 1); // 如果没找到dp[i] = per[1];if (i == res) res++;}return res;}
}

354. 俄罗斯套娃信封问题

1.题目描述

leetcode链接:354. 俄罗斯套娃信封问题
在这里插入图片描述

2.思路分析

与上一题相同,只是身高体重的区间换成了信封的长宽,方法完全一样。

直接动态规划会超时,所以可以还是使用二分查找来优化。

3.参考代码

class Solution {public int maxEnvelopes(int[][] envelopes) {int n = envelopes.length;Arrays.sort(envelopes, (a, b) -> (a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]));int[] dp = new int[n];Arrays.fill(dp, 1); // 初始化为1,表示当前信封int max = 0;// 二分查找for (int[] env : envelopes) {int left = 0, right = max;while (left < right) {int mid = (right - left) / 2 + left;if (dp[mid] < env[1]) {  // 要找的是dp数组中第一个小于当前h的位置left = mid + 1;} else {right = mid;}}dp[left] = env[1];if (left == max) {max++;}}return max;}
}

面试题 08.13. 堆箱子

1.题目描述

leetcode链接:面试题 08.13. 堆箱子
在这里插入图片描述

2.思路分析

动态规划:

本题与上两题相似,都是多维度下的最长递增子序列问题。这道题是三维,宽度,深度,高度都要大于上面的箱子。

同样的先按照各维进行排序。然后动态规划,注意每一次的dp[i]初始化为 box[i][2];

3.参考代码

class Solution {public int pileBox(int[][] box) {// 按宽度,深度,高度升序排列Arrays.sort(box, (a, b) -> (a[0] == b[0] ? (a[1] == b[1] ? a[2] - b[2] : a[1] - b[1]) : a[0] - b[0]));int[] dp = new int[box.length];int res = 0;for (int i = 0; i < box.length; i++) {dp[i] = box[i][2];for (int j = 0; j < i; j++) {if (box[j][0] < box[i][0] && box[j][1] < box[i][1] && box[j][2] < box[i][2]) {dp[i] = Math.max(dp[i], dp[j] + box[i][2]);}}res = Math.max(res, dp[i]);}return res;}
}

1691. 堆叠长方体的最大高度

1.题目描述

leetcode链接:1691. 堆叠长方体的最大高度
在这里插入图片描述在这里插入图片描述

2.思路分析

与上一题一致,只是多了一步,开始的时候需要先对每个正方体内部进行排序,升序排序后,高度在最后的位置,其余与上一题完全相同。

3.参考代码

class Solution {public int maxHeight(int[][] cuboids) {for (int[] cuboid : cuboids) {Arrays.sort(cuboid);}Arrays.sort(cuboids, (a, b) -> (a[0] == b[0] ? (a[1] == b[1] ? a[2] - b[2] : a[1] - b[1]) : a[0] - b[0]));int[] dp = new int[cuboids.length];int res = 0;for (int i = 0; i < cuboids.length; i++) {dp[i] = cuboids[i][2];for (int j = 0; j < i; j++) {if (cuboids[i][0] >= cuboids[j][0] && cuboids[i][1] >= cuboids[j][1] && cuboids[i][2] >= cuboids[j][2]) {dp[i] = Math.max(dp[i], dp[j] + cuboids[i][2]);}}res = Math.max(dp[i], res);}return res;}
}

406. 根据身高重建队列

1.题目描述

leetcode链接:406. 根据身高重建队列
在这里插入图片描述

2.思路分析

先按身高降序排序,身高相同,再按k值升序排序。

之后顺序遍历将元插入结果集。就是小的反而后插入相对应的索引。

示例:

输入: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
输出:
[[7, 0]]
[[7, 0], [7, 1]]
[[7, 0], [6, 1], [7, 1]]
[[5, 0], [7, 0], [6, 1], [7, 1]]
[[5, 0], [7, 0], [5, 2], [6, 1], [7, 1]]
[[5, 0], [7, 0], [5, 2], [6, 1], [4, 4], [7, 1]]

3.参考代码

class Solution {public int[][] reconstructQueue(int[][] people) {// 身高降序排,身高相同,k小的排前面Arrays.sort(people, (a, b) -> (a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]));List<int[]> list = new LinkedList<>();for (int[] p : people) {list.add(p[1], p);}return list.toArray(new int[people.length][]);}
}

http://chatgpt.dhexx.cn/article/uQqd0gdR.shtml

相关文章

输出最长递增子序列

目录 题目&#xff1a; 输入描述: 输出描述: 示例1 输入 输出 示例2 输入 输出 说明 备注: 思路分析&#xff1a; 改进&#xff1a; 得到最长子序列&#xff1a; 易错点&#xff1a; 代码展示&#xff1a; 题目&#xff1a; 给定数组arr&#xff0c;设长度为n&…

NC91 最长递增子序列

NC91 最长递增子序列 这道题n的范围是1e5&#xff0c;因此不能使用常规的dp[i]&#xff0c;表示以i结尾的最大的子序列&#xff0c;因为这个时间复杂度是n方级别。因此要换一种算法。 贪心二分&#xff0c;时间复杂度为O(nlogn) 下面说说贪心二分的解法&#xff0c;举例说明基…

Vue3 最长递增子序列详解

Vue3 最长递增子序列研究 本文初衷 彻底讲清楚 Vue3 源码中实现最长递增子序列的算法。 概念名词 **最长递增子序列&#xff1a;**在一个给定的数值序列中&#xff0c;找到一个子序列&#xff0c;使得这个子序列元素的数值依次递增&#xff0c;并且这个子序列的长度尽可能地…

Java 最长递增子序列_最长递增子序列问题 Java

最长递增子序列问题 LIS(longest increasing subsequence) 例如 给定一个数列&#xff0c;长度为N&#xff0c; 求这个数列的最长上升(递增)子数列(LIS)的长度. 以 1, 7, 2, 8, 3, 4 为例。 这个数列的最长递增子数列是 1 2 3 4&#xff0c;长度为4&#xff1b; 次长的长度为3&…

最长递增子序列

问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8},长度为4. 解法1:最长公共子序列法 这个问题可以转换为最长公共子序列问题。如…

动态规划设计方法详解最长递增子序列

很多读者反应&#xff0c;就算看了前文动态规划详解&#xff0c;了解了动态规划的套路&#xff0c;也不会写状态转移方程&#xff0c;没有思路&#xff0c;怎么办&#xff1f;本文就借助「最长递增子序列」来讲一种设计动态规划的通用技巧&#xff1a;数学归纳思想。 最长递增…

最长递增子序列(Longest Increasing Subsequence)

定义 最长上升子序列&#xff08;Longest Increasing Subsequence&#xff0c;LIS&#xff09;&#xff0c;在计算机科学上是指一个序列中最长的单调递增的子序列。 问题描述 给定一个长度为 N 的数组&#xff0c;找出一个最长的单调自增子序列&#xff08;不一定连续&#…

最长递增子序列问题(你真的会了吗)

目录 一.最长递增子序列问题I 二.最长递增子序列问题II 三. 最长递增子序列问题III 一.最长递增子序列问题I 1.对应牛客网链接 最长上升子序列(一)_牛客题霸_牛客网 (nowcoder.com) 2.题目描述&#xff1a; 3.解题思路 1.首先我们分析题意&#xff1a;最长递增子序列拆&#x…

UDP协议详细解析

一、基本概念 基本定义&#xff1a;UDP 是User Datagram Protocol的简称&#xff0c; 中文名是用户数据报协议&#xff0c;是OSI&#xff08;Open System Interconnection&#xff0c;开放式系统互联&#xff09; 参考模型中一种无连接的传输层协议&#xff0c;提供面向事务的…

tcp read 和 udp recvfrom

udp中写一个长度为0的数据报是可行的&#xff0c;这导致一个包含IP头部、udp头部和没有数据的IP数据报。这也意味着对于数据报协议&#xff0c;recvfrom返回0值也是可行的&#xff1a;它不表示对方已经关闭了连接&#xff0c;这与tcp套接口上read返回0值的情况不同。由于udp是无…

UDPTCP

目录 Socket 一.UDP 特点 基于UDP实现回显服务器 服务器 客户端 端口冲突 图解 二.TCP 特点 基于TCP实现回显服务器 服务器 客户端 图解 Socket Socket套接字&#xff0c;是由系统提供用于网络通讯的技术&#xff0c;是基于TCP/IP协议的网络通信的基本操作单元&#xff0c;基于…

Reliable UDP

Reliable UDP&#xff08;可靠的UDP&#xff09;是一套服务品质的增强&#xff0c;比如拥挤控制调整&#xff0c;数据重传&#xff0c;薄化服务器算法等&#xff0c;这些增强可以提高服务器在数据包丢失和网络拥挤的条件下向RTP客户表现品质良好的RTP流的能力。Reliable UDP’的…

TCP /UDP

TCP与UDP工作在传输层&#xff0c;在程序之间传数据&#xff08;视频&#xff0c;聊天&#xff0c;图片&#xff0c;网页&#xff09; TCP基于连接的&#xff0c;可靠的&#xff08;及时知对方接受/拒绝&#xff0c;是否传错&#xff09;&#xff08;文本&#xff0c;网页&…

UDP、TCP

传输层协议UDP、TCP 一、TCP/UDP的任务二、UDP1.UDP概述2.UDP报文格式3.使用UDP的应用层协议 三、TCP1.TCP概述2.TCP报文3.TCP三次握手4.四次挥手5.超时重传6.流量控制和快重传7.拥塞控制8.延迟应答、捎带应答9.粘包问题10.基于TCP的应用层协议 四、总结 一、TCP/UDP的任务 我们…

tcp udp proxy

服务目的 首先如下图所示&#xff1a; 作为一个内外网的通信&#xff0c;必须使用tcp 和 udp 的proxy 把内网和外网打通&#xff0c;比如中间是一个有两个网卡的路由器&#xff0c;打通以后&#xff0c;由proxy 发送数据到服务端&#xff0c;服务端按照上图处于外网。 服务端…

UDP-RTP协议解析

一、RTP协议 数据传输协议RTP&#xff0c;用于实时传输数据。RTP报文由两部分组成&#xff1a;报头和有效载荷 二、RTP的会话过程 当应用程序建立一个RTP会话时&#xff0c;应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成&#xff0c;有两个端口&a…

UDP 理解

这里需要指出的一点是&#xff0c;伪首部完全是虚拟的&#xff0c;它并不会和用户数据报一起被发送出去&#xff0c;只是在校验和的计算过程中会被使用到&#xff0c;伪首部主要来自于运载UDP报文的IP数据报首部&#xff0c;将源IP地址和目的IP地址加入到校验和的计算中可以验证…

关于TCP/UDP

目录 1、TCP协议 1.1 TCP协议格式 1.2 TCP协议原理 2、UDP协议 在学习TCP/UDP之前先来了解以下整体的通信传输&#xff0c;它是一个向下封装、向上分用的过程&#xff1a; 这是TCP/IP四层模型&#xff0c;所以要想实现通讯&#xff0c;通过TCP建立和断开连接是至关重要的&a…

UDP详解

1、UDP数据包格式 UDP 是User Datagram Protocol的简称&#xff0c; 中文名是用户数据报协议&#xff0c;是OSI&#xff08;Open System Interconnection&#xff0c;开放式系统互联&#xff09; 参考模型中一种无连接的传输层协议&#xff0c;提供面向事务的简单不可靠信息传…

TCPUDP相关介绍

TCP and UDP TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是面向连接的协议&#xff0c;也就是说&#xff0c;在收发数据前&#xff0c;必须和对方建立可靠的连接。 一个TCP连接必须要经过三次握手才能建立起来。断开连接需要四次挥手才…