LeetCode 300.Longest Increasing Subsequence 在一维数组中找最长序列(好题)
来源:互联网 发布:阿里云香港服务器能放 编辑:程序博客网 时间:2024/05/29 12:39
题目
Given an unsorted array of integers, find the length of longest increasing subsequence.
For example,
Given [10, 9, 2, 5, 3, 7, 101, 18]
,
The longest increasing subsequence is [2, 3, 7, 101]
, therefore the length is 4
. Note that there may be more than one LIS combination, it is only necessary for you to return the length.
Your algorithm should run in O(n2) complexity.
Follow up: Could you improve it to O(n log n) time complexity?
首先是O(n2)的方法,利于动态规划
模拟过程如下:
input[]: 10 92 5 3 7 10118
store[]: 1 1 1 2 23 4 4
public int lengthOfLIS(int[] nums) {if(nums==null || nums.length==0)return 0;int len = nums.length;int[] store = new int[len];for(int i=0;i<len;i++){store[i] = 1;for(int j = 0; j < i ;j++){if(nums[j]<nums[i]){store[i] = Math.max(store[i], store[j]+1);}}}int result = 1;for(int i=0;i<store.length;i++)result = Math.max(result, store[i]);return result;}
接下来扩展一下,把最长序列输出出来(可能多种,我只输出一个),思路是设定一个阈值(max=1),只要store[]中超过阈值的项写入列表List中,更新max,最后将max=1且比List[0]小的插入至List[0],长度加一,代码如下;
public List OutputOfLIS(int[] nums) {int max = 1; //判断当前最大;List<Integer> result_list = new ArrayList<Integer>();if(nums==null || nums.length==0)return null;int len = nums.length;int[] store = new int[len];for(int i=0;i<len;i++){store[i] = 1;for(int j = 0; j < i ;j++){if(nums[j]<nums[i]){if(store[i]<store[j]+1&&store[j]+1>max){max = store[j]+1;store[i] = store[j]+1;if(!result_list.contains(nums[i]))result_list.add(nums[i]);}}}}if(result_list.size()>0){//把第一个补全for(int i=0;i<len;i++){if(nums[i]<result_list.get(0)){result_list.add(0, nums[i]);return result_list;}}}else return result_list;return result_list;}}
其次是O(nlogn)的方法,用的是栈和折半查找
思路部分参考http://blog.csdn.net/yorkcai/article/details/8651895
开一个栈,将nums[0]入栈,每次取栈顶元素top和读到的元素nums[i](1<i<n)做比较,如果nums[i]> top 则将nums[i]入栈;如果nums[i]<= top则二分查找栈中的比nums[i]大的第1个数,并用nums[i]替换它。 最长序列长度即为栈的大小top。
input[]: 109253710118
栈的构造过程
10
9
2
2 5
2 3
2 3 7
2 3 7 101
2 3 7 18
2
2 5
2 3
2 3 7
2 3 7 101
2 3 7 18
代码如下
public int lengthOfLIS(int[] nums) {if(nums==null||nums.length==0)return 0;int[] stack = new int[nums.length]; //模拟一个栈 result代表栈的深度stack[0] = nums[0];for(int i=1;i<nums.length;i++)stack[i] = Integer.MAX_VALUE; //赋值成为nums[0],MAX_VALUE,MAX_VALUE......int result = 0;for(int i=1;i<nums.length;i++){if(nums[i]>stack[result]){//当前元素比栈顶还大result ++;stack[result] = nums[i];//System.out.print("!!!:"+result+","+" ");}else if(nums[i]<stack[result]){int mid = Arrays.binarySearch(stack, 0, result+1, nums[i]);//System.out.print("!!!:"+result+","+mid+" ");if(mid<0)stack[-mid -1] = nums[i];}//for(int s=0;s<=result;s++)//System.out.print(stack[s]+" ");//System.out.println();}return result+1;
值得注意的,O(nlogn)
input[]: 10925371016
栈的构造过程
10
9
2
2 5
2 3
2 3 7
2 3 7 101
2 3 6 101 //这一次替换了最长序列,与预期最长序列不同,但是长度却相同
2
2 5
2 3
2 3 7
2 3 7 101
2 3 6 101 //这一次替换了最长序列,与预期最长序列不同,但是长度却相同
分析:
当nums[i]>top时,top+1,与预期相同;
当nums[i]<top时, 这时num[i]会替换栈里面的某一个元素,top大小不变,但是序列发生了变化;
如果只求个数的话,这个算法比较高效;但如果要求打印出序列时,就只能用动态规划的方法。
1 0
- LeetCode 300.Longest Increasing Subsequence 在一维数组中找最长序列(好题)
- LeetCode 300. Longest Increasing Subsequence(最长递增子序列)
- leetcode 300. Longest Increasing Subsequence 最长上升序列数
- leetcode 300. Longest Increasing Subsequence-最长子序列|动态规划
- 【LeetCode】300.Longest Increasing Subsequence最长递增子序列LIS
- leetcode 300. Longest Increasing Subsequence 最长递增子序列LISS
- LeetCode--Longest Increasing Subsequence (最长递增子序列)Python
- 300. Longest Increasing Subsequence 最长子序列
- 最长递增子序列O(NlogN)算法(leetcode 300. Longest Increasing Subsequence )
- LeetCode 329. Longest Increasing Path in a Matrix 在二维数组中寻找最长递增序列
- leetcode Longest Increasing Subsequence 最长递增子序列
- [LeetCode] Longest Increasing Subsequence 最长递增子序列的长度
- 【LeetCode 300 Longest Increasing Subsequence】最长递增子序列
- leetcode 674. Longest Continuous Increasing Subsequence 最长连续递增序列
- leetcode 300.Longest Increasing Subsequence(最长递增子序列) O(nlogn)算法
- leetcode(300)—— Longest Increasing Subsequence(最长递增子序列)
- LeetCode-674:Longest Continuous Increasing Subsequence (最长连续增序列)
- 300. Longest Increasing Subsequence最长递增子序列
- 301. Remove Invalid Parentheses
- 在Ubuntu 12.04 LTS 64bit初始化Android编译环境后,遇到重启后卡住在Ubuntu logo,进不了desktop
- Go语言学习之net包(The way to go)
- Flask 快速入门
- U3D的碰撞(Collision)和触发(Trigger)
- LeetCode 300.Longest Increasing Subsequence 在一维数组中找最长序列(好题)
- IOS开发中的window,controller,view
- 278. First Bad Version
- JSon实体类快速生成插件 GsonFormat 1.2.2
- Hibernate关联映射——一对多(多对一)
- tomcat服务器与Http协议之请求(get请求、post请求)和响应
- red_hat 安装 yum
- find命令之xargs
- 他山界面开发框架OHUI v29.0.1