[LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)
描述
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
解析
动态规划
本文讲一种设计动态规划的通用技巧:数学归纳思想。
动态规划的核心设计思想是数学归纳法。
相信大家对数学归纳法都不陌生,高中就学过,而且思路很简单。比如我们想证明一个数学结论,那么我们先假设这个结论在 k<n 时成立,然后想办法证明 k=n 的时候此结论也成立。如果能够证明出来,那么就说明这个结论对于 k 等于任何数都成立。
类似的,我们设计动态规划算法,不是需要一个 dp 数组吗?我们可以假设 dp[0...i-1] 都已经被算出来了,然后问自己:怎么通过这些结果算出 dp[i]?
直接拿最长递增子序列这个问题举例你就明白了。不过,首先要定义清楚 dp 数组的含义,即 dp[i] 的值到底代表着什么?
我们的定义是这样的:dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列的长度。
动态规划的重头戏是,要思考如何进行状态转移,这里就可以使用数学归纳的思想:
我们已经知道了 dp[0...4] 的所有结果,我们如何通过这些已知结果推出 dp[5]呢?
根据刚才我们对 dp 数组的定义,现在想求 dp[5] 的值,也就是想求以 nums[5] 为结尾的最长递增子序列。
nums[5] = 3,既然是递增子序列,我们只要找到前面那些结尾比 3 小的子序列,然后把 3 接到最后,就可以形成一个新的递增子序列,而且这个新的子序列长度加一。
当然,可能形成很多种新的子序列,但是我们只要最长的,把最长子序列的长度作为 dp[5] 的值即可。
还有一个细节问题,dp 数组应该全部初始化为 1,因为子序列最少也要包含自己,所以长度最小为 1。
二分
上面链接
代码
public int lengthOfLIS(int[] nums) {
if (null == nums || nums.length <= 0) {
return 0;
}
int len = nums.length;
int[] dp = new int[len];
for (int i = 0; i < len; i++) {
dp[i] = 1;
}
int res = 1;//当数组只有1个数,最小长度就是1
for (int i = 1; i < len; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
res = Math.max(res, dp[i]);
}
}
}
return res;
}
[LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)的更多相关文章
- Java实现 LeetCode 300 最长上升子序列
300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10 ...
- LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)
题目描述 给出一个无序的整形数组,找到最长上升子序列的长度. 例如, 给出 [10, 9, 2, 5, 3, 7, 101, 18], 最长的上升子序列是 [2, 3, 7, 101],因此它的长度是 ...
- LeetCode 300——最长上升子序列
1. 题目 2. 解答 2.1. 动态规划 我们定义状态 state[i] 表示以 nums[i] 为结尾元素的最长上升子序列的长度,那么状态转移方程为: \[state[i] = max(state ...
- leetcode 300最长上升子序列
用递归DFS遍历所有组合肯定积分会超时,原因是有很多重复的操作,可以想象每次回溯后肯定会有重复操作.所以改用动态规划.建立一个vector<int>memo,初始化为1,memo[i]表示 ...
- Leetcode——300. 最长上升子序列
题目描述:题目链接 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101], ...
- Leetcode 300.最长上升子序列
最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的 ...
- Luogu 3402 最长公共子序列(二分,最长递增子序列)
Luogu 3402 最长公共子序列(二分,最长递增子序列) Description 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作业: ...
- 1. 线性DP 300. 最长上升子序列 (LIS)
最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ...
- 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))
算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ...
随机推荐
- matlab基本函数sort
一起来学演化计算-matlab基本函数sort 觉得有用的话,欢迎一起讨论相互学习~Follow Me sort 对数组元素排序 语法 B = sort(A) 按照大小不等于1的第一个数组维度对A的元 ...
- Django models中的meta选项
通过一个内嵌类 "class Meta" 给你的 model 定义元数据, 类似下面这样: class Foo(models.Model): bar = models.CharFi ...
- Swift4.0复习基本语法简介
1.五种类型: 包含五种类型——枚举(enum).结构体(struct).类(class).协议( protocol)以及函数类型(function types). 2.变量对象:var 3.常量对象 ...
- jenkins--master/slave模式---master是容器版---slave是非容器版
实验架构: 192.168.0.96 gitlab 192.168.0.97 jenkins.tomcat 192.168.0.98 harbor.docker集群.git.jdk.maven 1.先 ...
- 【linux学习笔记四】文件搜索命令
一 文件搜索 locate //在后台数据库中按文件名搜索 搜索速度更快 locate 文件名 //locate命令所搜索的后台数据库 /var/lib/mlocate //更新数据库 updated ...
- RabbitMQ官方教程四 Routing(GOLANG语言实现)
在上一教程中,我们构建了一个简单的日志记录系统. 我们能够向许多消费者广播日志消息. 在本教程中,我们将向其中添加功能-我们将使仅订阅消息的子集成为可能. 例如,我们将只能将严重错误消息定向到日志文件 ...
- 【GStreamer开发】GStreamer播放教程04——既看式流
目的 在<GStreamer基础教程--流>里面我们展示了如何在较差的网络条件下使用缓冲这个机制来提升用户体验.本教程在<GStreamer基础教程--流>的基础上在扩展了一下 ...
- git将代码提交到多个远程仓库
在项目目录下执行: git remote set-url --add origin http://mayun.cn/xxx/adsdsdsdcelery-demo.git 即可添加一个远程仓库. 再执 ...
- AJAX-前后端交互的艺术
AJAX-前后端交互的艺术 为什么要用AJAX? 当我们通过提交表单向服务器提交内容,或者进行一些其他操作,均涉及到了与浏览器之间的交互,传统的方式与AJAX方式的处理方法是不同的 传统方式:用户触发 ...
- 异常查错java.net.SocketException: Connection reset
用httpclient访问后台接口报错java.net.SocketException: Software caused connection abort: recv failed,百度了一圈都说是由 ...