题目:给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4.

解析思路1:

建立一个临时数组new_arr(用于存放一组最长上升子列),首先将nums[0]插入其中,然后遍历nums[1:]

  • 如果遍历到的元素val <= new_arr[0],我们更新new_arr[0]=val(也就是遍历到的元素比最长上升子序列中的最小元素小,我们通过贪心的策略,当然是越小越好,所以替换之前元素)
  • 如果new_arr[0] < val <= new_arr[-1],我们通过二分搜索法找到第一个>=val的元素位置,然后用val替换掉它(和上面的做法相同)
  • 如果new_arr[-1] < val,我们更新new_arr.append(val)(也就是新加入的元素比最长上升子序列中的最后一个元素大,那么必然构成解)

---------------------

作者:coordinate_blog

来源:CSDN

原文:https://blog.csdn.net/qq_17550379/article/details/82871892

实现代码:

class Solution:
def lengthOfLIS(self, nums) -> int:
length = len(nums)
new_arr = [] # 最长上升子列数组
if length == 0: # 原数组为空
return 0
elif length == 1: # 原数组只有一个元素
return 1
else:
new_arr.append(nums[0])
for i in range(1, length):
if nums[i] <= new_arr[0]: # 如果遍历的元素比子列中最小值还小或相等,则替换
new_arr[0] = nums[i]
elif (new_arr[0] < nums[i]) and (nums[i] <= new_arr[-1]): # 如果遍历的元素值大小在子列中间,则查找到第一个大于或等于此元素的子列元素,进行替换;new_arr目前是已经有序的,所以可以用二分查找提高检索效率
low,high = 0,len(new_arr)-1
while low <= high:
mid = (low+high)//2
if new_arr[mid] >= nums[i]:
new_arr[mid] = nums[i]
break
else:
low = mid + 1
elif nums[i] > new_arr[-1]: # 如果遍历的元素比子列最大元素还大,则追加到子列尾部
new_arr.append(nums[i])
return len(new_arr)

执行用时 : 52 ms, 在Longest Increasing Subsequence的Python3提交中击败了96.97% 的用户

内存消耗 : 13.1 MB, 在Longest Increasing Subsequence的Python3提交中击败了96.54% 的用户

解题思路2:

依次求出以初始序列中各个元素为尾元素的最长递增子序列的长度,然后通过对其大小的判断,不断更新最长递增子序列的最大长度,每次更新最大长度的时候将当前递增子序列尾元素的前向元素添加进来,最后添加最长递增子序列的尾元素,由此,即可求出最长递增子序列长度,也可求出最长递增子序列(不唯一)。

  • 如对于初始序列[10,9,2,5,3,7,101,18],要依次计算出以10,9,2,5,3,7,101,18作为尾元素的最长递增序列的长度,然后去进行大小判断和更新。
  • 以10结尾的最长递增子序列:[10]
  • 以9结尾的最长递增子序列:[9]
  • 以2结尾的最长递增子序列:[2]
  • 以5结尾的最长递增子序列:[2,5]
  • 以3结尾的最长递增子序列:[2,3]
  • 以7结尾的最长递增子序列:[2,3,7]或[2,5,7]
  • 以101结尾的最长递增子序列:[2,3,7,101]或[2,5,7,101]
  • 以18结尾的最长递增子序列:[2,3,7,18]或[2,5,7,18]

    每往后计算一个就将其最长递增子序列长度与前一个比较

实现代码:


import java.util.ArrayList;
import java.util.Scanner;
import java.util.List; public class SubSequence {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] s = new int[n];
for(int i=0; i<n; i++){
s[i] = sc.nextInt();
}
int max_len = getSubSequenceLen(n, s);
System.out.println("最长递增子序列长度:"+max_len);
} public static int getSubSequenceLen(int n, int[] s){
int[] liss = new int[n]; // 以各元素结尾的最长递增子序列长度
int[] pre = new int[n]; // 以各元素结尾的最长递增子序列的当前元素的前向元素
List<Integer> maxSubSequence = new ArrayList<Integer>();
int max_len = 1; // 最长递增子序列长度
int end_index = 0; // 长递增子序列尾元素地址
// 初始化
for(int i=0; i<n; i++){
liss[i] = 1;
pre[i] = s[i];
}
for(int p=1; p<n; p++){
for(int q=0; q<p; q++){
if(s[q]<s[p] && liss[q]+1>liss[p]){
liss[p] = liss[q]+1;
pre[p] = s[q];
end_index = p;
}
}
if(max_len<liss[p]){
max_len = liss[p];
maxSubSequence.add(pre[p]); // 将最长递增子序列中当前元素的前向元素添加进来
}
}
maxSubSequence.add(s[end_index]); // 将最长递增子序列的尾元素添加进来
System.out.println("最长递增子序列:"+maxSubSequence);
return max_len;
}
}

思路来源:https://blog.csdn.net/qq_34369618/article/details/72852740

代码仅供参考

LeetCode--300. 最长递增子序列的更多相关文章

  1. 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))

    算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ...

  2. Leetcode 673.最长递增子序列的个数

    最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[ ...

  3. Leetcode 300.最长上升子序列

    最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的 ...

  4. [LeetCode] 300. 最长上升子序列 ☆☆☆(动态规划 二分)

    https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/dong-tai-gui-hua-she-ji-fan ...

  5. Java实现 LeetCode 673 最长递增子序列的个数(递推)

    673. 最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, ...

  6. Java实现 LeetCode 300 最长上升子序列

    300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10 ...

  7. leetcode 300最长上升子序列

    用递归DFS遍历所有组合肯定积分会超时,原因是有很多重复的操作,可以想象每次回溯后肯定会有重复操作.所以改用动态规划.建立一个vector<int>memo,初始化为1,memo[i]表示 ...

  8. Leetcode——300. 最长上升子序列

    题目描述:题目链接 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101], ...

  9. LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)

    题目描述 给出一个无序的整形数组,找到最长上升子序列的长度. 例如, 给出 [10, 9, 2, 5, 3, 7, 101, 18], 最长的上升子序列是 [2, 3, 7, 101],因此它的长度是 ...

  10. LeetCode 300——最长上升子序列

    1. 题目 2. 解答 2.1. 动态规划 我们定义状态 state[i] 表示以 nums[i] 为结尾元素的最长上升子序列的长度,那么状态转移方程为: \[state[i] = max(state ...

随机推荐

  1. Docker笔记(十二):Docker Compose入门

    1. Compose简介 Docker Compose是Docker官方的用于对Docker容器集群实现编排,快速部署分布式应用的开源项目.Docker Compose通过docker-compose ...

  2. 使用不同的C++支持库的模块混合开发时,引发异常展开不正常,抛异常竟引出一个SIGSEGV

    如果你使用gcc对一部分模块进行了GNUMake的编译,这些编译出动态库使用在Gradle编译框架下的项目.那么就有可能出现题目中的情况,使用不同的C++支持库的模块混合开发时,引发异常展开不正常. ...

  3. HTTP基础及telnet基本用法

    HTTP概况 ​ 20世纪90年代初期,一个主要的新兴应用即万维网(World Wide Web)登上了舞台.Web是一个引起公众注意的因特网应用.Web的应用层协议是超文本传输协议(HTTP),它是 ...

  4. Asis CTF 2016 b00ks理解

    ---恢复内容开始--- 最近在学习堆的off by one,其中遇到这道题,萌新的我弄了大半天才搞懂,网上的很多wp都不是特别详细,都得自己好好调试. 首先,这题目是一个常见的图书馆管理系统,虽然我 ...

  5. 堆 堆排序 优先队列 图文详解(Golang实现)

    引入 在实际应用中,我们经常需要从一组对象中查找最大值或最小值.当然我们可以每次都先排序,然后再进行查找,但是这种做法效率很低.哪么有没有一种特殊的数据结构,可以高效率的实现我们的需求呢,答案就是堆( ...

  6. element 根据某一个属性合并列

    通过 span-method 绑定方法 objectSpanMethod方法 this.getSpanArr(this.tableData); //this.tableData 指接口取到的数据 // ...

  7. mysqldump工具实现mysql数据库的备份还原

    简介 冷.温.热备份 冷备:读写操作均不可进行 温备:读操作可执行:但写操作不可执行 热备:读写操作均可执行 MyISAM:温备,不支持热备 InnoDB:都支持 不管是热备还原还是冷备还原,还原时都 ...

  8. 【CPLUSOJ】【动态规划】最短回文串

    题目链接 [问题描述] 如果一个字符串正过来读和倒过来读是一样的,那么这个字符串就被称作回文串.例如abcdcba,abcddbca就是回文串,而abcdabcd不是. 你要解决的问题是:对于任意一个 ...

  9. Java并发之synchronized关键字和Lock接口

    欢迎点赞阅读,一同学习交流,有疑问请留言 . GitHub上也有开源 JavaHouse,欢迎star 引用 当开发过程中,我们遇到并发问题.怎么解决? 一种解决方式,简单粗暴:上锁.将千军万马都给拦 ...

  10. PL真有意思(八):其它程序设计模型

    前言 在之前几篇我们讨论的语法.语义.命名.类型和抽象适用于所有语言.然而我们的注意力都主要集中在命令式语言上,现在这篇来看看其它范式的语言.函数式和逻辑式语言是最主要的非命令式语言. 函数式语言 命 ...