算法14-求最长子序列

article/2025/9/28 9:58:32

题目:
给定数组arr。求最长的有序子序列的长度,返回长度int

分析:
1 要求的子串是有序的,就要比大小
2 用最暴力大方法,看成窗口问题,每一个元素求出它左边的最长序列子串,写入一个数组dp,dp中的最大值就是要求的结果,这样的方法时间复杂度为O(N^2)
3 进阶算法:除了记录每个元素与左边的最大序列子串的数组dp外。再建一个数组end,其实在使用上相当于一个有序链表,每一个元素插入的位置是固定的,就是它要替换第一个大于它的值,若end中最后一个元素比要插入的元素还小,就append到end末尾,这样end中从0开始到插入的元素的长度,就是插入元素的最大有序子序列长度

//利用两个数组,遍历list,步骤:

//1 先将第i个元素放入end:

  • 当i的值小于当前end的最后一个元素,则插入end中第一个大于i的值;
  • 否则就append到end的最后

//2 将插入end的位置+1记入dp表,返回dp中最大值

在这里插入图片描述

代码:
两种时间复杂度的解法

package main
import("fmt"
)
// list:=[]int{4,1,3,2,3,9,5,6,9}
//窗口   O(n^2)
func process(list []int){dp:=[]int{1}for i :=1;i<len(list);i++{max:=0fmt.Println(list[i])fmt.Println(dp)cours:=ifor cours>=1{if list[cours-1]<list[cours]{if dp[cours-1]>max{max=dp[cours-1]}}cours--fmt.Println(cours)}dp=append(dp,max+1)}fmt.Println(dp)
}
//O(N*LOGN)
//利用两个数组,遍历list,
//1 先将第i个元素放入end:当i的值小于当前end的最后一个元素,则插入end中第一个大于i的值,否则就append到end的最后
//2 将插入end的位置+1记入dp表,返回dp中最大值
func process1(list []int){end:=[]int{list[0]}//第i个元素,替换end中大于它的第一个数,插入的位置+1就是它的最长子序列,并更新到dp对应的位置dp:=[]int{1}//用来记录第i个元素的最长子序列,值来自于将数据插入end后end的长度(长度是从1开始,即个数)fmt.Println(dp)fmt.Println(end)for i :=1;i<len(list);i++{fmt.Println(list[i])//如果i的值小于end中最后一个的值,找到第一个大于i的值,替换它if end[len(end)-1]>=list[i]{fmt.Println(end[len(end)-1],list[i])idx,j:=-1,1for {//目标值每次加1,从数组中找到它后退出,否则返回-1fmt.Println(end,list[i]+j)idx,_=binsearch(end,list[i]+j)fmt.Println(idx)j+=1if idx!=-1{//不等-1表示找到了,退出break}}end[idx]=list[i]fmt.Println(end)//把插入end的位置+1记录到dp中,这个值就是i的最长子序列dp=append(dp,len(end[0:idx+1]))}else{如果end的最后一个元素小于i的值,就直接append到end,将end的长度+1记录到dpend=append(end,list[i])dp=append(dp,len(end))}}fmt.Println(end)fmt.Println(dp)}
func binsearch(list []int,tar int) (int,int){left:=0right:=(len(list)-1)for left<=right{mid:=(left+right)/2idx:=mid// fmt.Println(mid)if list[mid]==tar{return idx,list[idx]}if list[mid]>tar{right=mid-1idx=right}else{left=mid+1idx=left}}return -1,-1}
func main(){list:=[]int{1,3,5,6,7,47,18,22,35,25,40,42,9}// list:=[]int{3,2,1,2,3,0,4,6,2,7}process1(list)// fmt.Println()// list:=[]int{1,3,5,6,7,9,18,22,35,36,40,42,47}// fmt.Println(binsearch(list,3))}

总结:

1 从end找第一个大于要插入的元素,用到了二分搜索
2 二分搜索没有用到递归,用for循环控制直到命中,注意for循环的条件一定是left小于等于right


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

相关文章

最长子序列——动态规划

动态规划算法通常用于求解具有某种最优性质的问题。动态规划算法与分治法类似&#xff0c;其基本思想也是将待求解问题分解成若干个子问题&#xff0c;先求解子问题&#xff0c;然后从这些子问题的解得到原问题的解。与分治法不同的是&#xff0c;适合于用动态规划求解的问题&a…

最长公共子串与最长子序列

一 序 本文属于《图解算法》系列&#xff0c;上一篇整理了动态规划&#xff0c;动态规划可以帮助我们解决给定约束条件下找到最优解&#xff0c;例如背包问题。 在问题可分解为彼此独立且离散的子问题时&#xff0c;就可使用动态规划来解决。 在看个例子&#xff0c;求两个字…

动态规划:最长子序列

最长公共子序列&#xff1a; 链接&#xff1a;https://www.nowcoder.com/questionTerminal/9ae56e5bdf4f480387df781671db5172 题目&#xff1a; 我们有两个字符串m和n&#xff0c;如果它们的子串a和b内容相同&#xff0c;则称a和b是m和n的公共子序列。子串中的字符不一定在原字…

C++最长子序列

LeedCode-300. 最长上升子序列 LeetCode-300. 最长上升子序列 方法一&#xff1a;O(n^2)可能会超时&#xff1b;方法二&#xff1a;贪心二分法&#xff0c;使用lower_bound()&#xff1b; 下面是贪心二分算法&#xff1a; 由于要得到最长的递增子序列&#xff0c;就要让序列…

数组:最长子序列问题四种解法

数组&#xff1a;最长子序列问题四种解法 问题描述&#xff1a; 给定一个整数数组 nums &#xff0c;找到一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 示例 1 : 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子…

动态规划:最长子序列问题

关于动态规划中的最长子序列问题有很多优秀的解读&#xff0c;在这里推荐一位博主的关于最长子序列的文章&#xff0c;非常不错&#xff0c;配有大量的图片和文字解答&#xff0c;在这里推荐给大家。本文章转载自这里 1.基本概念 首先需要科普一下&#xff0c;最长公共子序列…

一道有趣的最长子序列问题

一道有趣的最长子序列问题 – 潘登同学的金融经济学笔记 文章目录 一道有趣的最长子序列问题 -- 潘登同学的金融经济学笔记 来源求解递推公式算法实现 来源 前几天在刷视频的时候&#xff0c;发现了这样一道题 所谓子序列就是一个序列 a i 1 , a i 2 , ⋯ , a i n a_{i1},a_{…

最长子序列最长子串的题型汇总

1.最长公共子序列的长度 题目&#xff1a;对于两个字符串&#xff0c;请设计一个高效算法&#xff0c;求他们的最长公共子序列的长度&#xff0c;这里的最长公共子序列定义为有两个序列U1,U2,U3...Un和V1,V2,V3...Vn,其中Ui&ltUi1&#xff0c;Vi&ltVi1。且A[Ui] B[Vi…

动态规划解最长子序列问题

动态规划法 经常会遇到复杂问题不能简单地分解成几个子问题&#xff0c;而会分解出一系列的子问题。简单地采用把大问题分解成子问题&#xff0c;并综合子问题的解导出大问题的解的方法&#xff0c;问题求解耗时会按问题规模呈幂级数增加。 为了节约重复求相同子问题的时间&…

最长****子序列

&#xff08;在研读大佬写的博客后&#xff0c;打算记录下自己学习过程&#xff09; 通过最长上升子序列的拓展了解到&#xff0c;其实这是一个系列的问题主要代表有&#xff1a; 1 最长上升子序列 2 最长不上升子序列 3 最长下降子序列 4 最长不下降子序列 就以最长上升子…

最长公共子序列

最长公共子序列&#xff08;Longest Common Subsequence&#xff0c;简称 LCS&#xff09;是一道非常经典的面试题目&#xff0c;因为它的解法是典型的二维动态规划&#xff0c;大部分比较困难的字符串问题都和这个问题一个套路&#xff0c;比如说编辑距离。而且&#xff0c;这…

最长公共子序列(LCS) 过程图解

1.基本概念 首先需要科普一下&#xff0c;最长公共子序列&#xff08;longest common sequence&#xff09;和最长公共子串&#xff08;longest common substring&#xff09;不是一回事儿。什么是子序列呢&#xff1f;即一个给定的序列的子序列&#xff0c;就是将给定序列中零…

最长子序列问题详解

提到最长子序列问题&#xff0c;想必大家都不陌生&#xff0c;今天我主要想分享一下我对子序列问题的一些理解&#xff1a; 先拿最长上升子序列问题来说吧&#xff1a; 很明显这是一个动态规化问题&#xff0c;仔细想想也不难得出其状态转移方程 首先介绍一下dp[]数组的含义…

如何查看pip版本

Windows系统如何查看pip版本 直接运行pip show pip

python之pip版本问题

我们在默认安装python软件之后&#xff0c;其自行安装的pip的版本可能比较落后。我们使用pip安装模块的时候经常提示安装失败&#xff0c;查看安装失败原因&#xff0c;部分是因为pip不是最新版本需要升级版本才能继续安装&#xff0c;因此写下一点小心得&#xff0c;让我们都能…

pip 查看可安装版本

pip 查看可安装版本 pip版本&#xff1a; pip -V pip 20.1.1 from /usr/lib/python2.7/site-packages/pip (python 2.7) 查看pip可安装版本 import pip._internal.utils.compatibility_tags print(pip._internal.utils.compatibility_tags.get_supported())

python如何查看pip版本并且升级pip

第一次写Python的学习经历 我之前也安装过Python,今天&#xff0c;终于重新安装了64位的windows的Python,于是在命令行输入&#xff1a;“pip list”出现以下的提示&#xff1a; 这个提示以前也出现过&#xff0c;但是看不懂&#xff0c;也不知道怎么处理&#xff0c;然后又胡…

python pip 查找指定安装包版本信息

一、windows操作系统 pip list | findstr 查找的包&#xff08;支持模糊查询&#xff09;例&#xff1a; pip list | findstr huawei结果&#xff1a; 二、linux操作系统 pip list | grep 查找的包&#xff08;支持模糊查询&#xff09;

更新pip版本

更新pip版本 从报错来看是因为pip版本为20.2.3&#xff0c;但当前可用版本是21.0.1 python -m ensurepippython -m pip install --upgrade pippip list设置镜像默认源 #临时使用 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package #设置默认源 pip inst…