编程之美——longest incremental sequence(LIS)

解法一:通过遍历得到(0:i)的LIS,时间复杂度O(N^2);

具体思路于代码,如下:

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4
 5 int longSub(int arr[],int n);
 6
 7 int main()
 8 {
 9     int arr[8]={1,-1,2,-3,4,-5,6,-7};
10     cout<<longSub(arr,8)<<endl;
11     return 0;
12 }
13
14 int longSub(int arr[],int n)
15 {
16     vector<int>LIS;
17
18     for(int i=0;i<n;++i)
19     {
20         //初始化默认长度为1
21         LIS.push_back(1);
22         for(int j=0;j<i;++j)
23         {
24             //更新LIS[I],得到LIS[I]最大值
25             if(arr[i]>arr[j]&&LIS[j]+1>LIS[i])
26                 LIS[i]=LIS[j]+1;
27         }
28     }
29
30     int maxLis=0;
31     //返回最大值
32     for(int i=0;i<LIS.size();++i)
33         if(LIS[i]>maxLis)
34             maxLis=LIS[i];
35
36     return maxLis;
37 }

解法二:希望找到前i个元素的中的一个递增序列,使其中最大元素比arr[i]小,并且尽可能长;时间复杂度O(N^2),若将其中查找改为二分查找,则时间复杂度O(N*logN)

代码如下:

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4
 5 int longSub(int arr[],int n);
 6 int minArr(int arr[],int n);
 7
 8 int main()
 9 {
10     int arr[8]={1,-1,2,-3,4,-5,6,-7};
11     cout<<longSub(arr,8)<<endl;
12     return 0;
13 }
14
15 int longSub(int arr[],int n)
16 {
17     //LIS:记录历史递增序列
18     //maxV:记录历史递增序列中最大值
19     vector<int>LIS;
20     vector<int>maxV;
21
22     maxV.push_back(minArr(arr,n)-1);
23     maxV.push_back(arr[0]);
24
25     //初始化最长递增序列长度
26     int maxLIS=1;
27
28     for(int i=1;i<n;++i)
29     {
30         //初始化
31         LIS.push_back(1);
32         int j;
33
34         //更新得到最长LIS,时间复杂度O(N^2)
35         for(j=maxLIS;j>=0;--j)
36         {
37             if(arr[i]>maxV[j])
38             {
39                 LIS[i]=j+1;
40                 break;
41             }
42         }
43
44           //如果当前最长序列大于最长递增序列长度,更新
45         if(LIS[i]>maxLIS)
46         {
47             maxLIS=LIS[i];
48             maxV[LIS[i]]=arr[i];
49         }
50         //更新maxV[j+1],取较小值
51         else if(arr[i]<maxV[j+1]&&arr[i]>maxV[j])
52             maxV[j+1]=arr[i];
53     }
54     return maxLIS;
55 }
56
57 int minArr(int arr[],int n)
58 {
59     int tmp=arr[0];
60     for(int i=0;i<n;++i)
61         if(arr[i]<tmp)
62             tmp=arr[i];
63     return tmp;
64 }

编程之美——longest incremental sequence(LIS)

时间: 2024-10-13 08:48:31

编程之美——longest incremental sequence(LIS)的相关文章

leetcode&amp;编程之美——博文目录

leetcode刷题整理: 1——Two Sum(哈希表hashtable,map) 2——Add Two Numbers(链表) 3——Longest Substring Without Repeating Characters(set,哈希表,两个指针) 9——Palindrome Number (数学问题) 11——Container With Most Water(两个指针) 12——Integer to Roman(string,数学问题) 13——Roman to Integer(s

486E - LIS of Sequence(LIS)

题意:给一个长度为n的序列,问每个数关于序列的LIS(longest increasing sequence)是什么角色.这里分了三种: 1.此数没有出现在任意一条LIS中 2.此数出现在至少一条但是不是全部的LIS中 3.此数出现在所有的LIS中 解法:nlgn的LIS算法可以求出以每个i位置结束的LIS长度up[i].出现在LIS的数其实就是一个dag,找出那些某层唯一数值的数就行.LIS算法后,从后向前扫,维护所以长度的最大值,这中间可以判断某长度有几个值,如果某些长度有多个位置则他们都属

编程之美之实时排名算法

首先来看一个实时排名算法 参考文献 某海量用户网站,用户拥有积分,积分可能会在使用过程中随时更新.现在要为该网站设计一种算法,在每次用户登录时显示其当前积分排名.用户最大规模为2亿:积分为非负整数,且小于100万. 存储结构 首先,我们用一张用户积分表user_score来保存用户的积分信息. 表结构: 示例数据: 下面的算法会基于这个基本的表结构来进行. 算法1:简单SQL查询 首先,我们很容易想到用一条简单的SQL语句查询出积分大于该用户积分的用户数量: select 1 + count(t

编程之美-数组中最长递增子序列(包括输出)

#include <iostream> #define N 8 using namespace std; int main(){ int a[N]={1,-1,2,-3,4,-5,6,-7}; int lis[N]; int result[N];//结果 for(int i=0;i<N;i++) result[i]=0; for(int i=0;i<N;i++) { lis[i]=1; for (int j=0;j<i; j++) { if( a[i]> a[j] &a

编程之美之最短摘要生成

书上给出了最短摘要的描述即算法,简单来说就是: 扫描过程始终保持一个[pBegin,pEnd]的range,初始化确保[pBegin,pEnd]的range里包含所有关键字 .然后每次迭代,尝试调整pBegin和pEnd: 1.pBegin递增,直到range无法包含所有关键字 2.pEnd递增,直到range重新包含所有关键字 计算新的range,与旧的range相比,看是否缩短了,如果是,则更新 不考虑关键字的先后顺序 .这里给出最短摘要算法的几个应用,首先是leetcode上面的两题: M

LeetCode开心刷题五十六天——128. Longest Consecutive Sequence

最近刷题进展尚可,但是形式变化了下,因为感觉眼睛会看瞎,所以好多写在纸上.本来想放到文件夹存储起来,但是太容易丢了,明天整理下,赶紧拍上来把 今晚是周末,这一周都在不停的学学学,我想下周怕是不能睡午觉了,中午回去床对我的诱惑太大了,我得想办法,一进门先把被褥收起来,再放个欢快的歌,中午少吃点,加油小可爱 之前欠下的烂帐,把太多简单题做完,导致剩下的都是难题,所以万万记住一点捷径都不要走 128看花花酱大神的解法,发现对hashtable的了解十分不足,甚至一些常见函数都不知道是干什么的 这道题涉

LeetCode OJ - Longest Consecutive Sequence

这道题中要求时间复杂度为O(n),首先我们可以知道的是,如果先对数组排序再计算其最长连续序列的时间复杂度是O(nlogn),所以不能用排序的方法.我一开始想是不是应该用动态规划来解,发现其并不符合动态规划的特征.最后采用类似于LRU_Cache中出现的数据结构(集快速查询和顺序遍历两大优点于一身)来解决问题.具体来说其数据结构是HashMap<Integer,LNode>,key是数组中的元素,所有连续的元素可以通过LNode的next指针相连起来. 总体思路是,顺序遍历输入的数组元素,对每个

编程之美-分层遍历二叉树

问题:给定一个二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号.那么分层遍历如图的二叉树,正确的输出应该为: <span style="font-size:14px;">1 2 3 4 5 6 7 8</span> 书中还给出了问题2:打印二叉树中的某层次的节点(从左到右),其中根结点为第0层,成功返回true,失败返回false 分析与解法 关于二叉树的问题,由于其本身固有的

Binary Tree Longest Consecutive Sequence

Given a binary tree, find the length of the longest consecutive sequence path. The path refers to any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The longest consecutive path need to be from p