算法题 |
算法刷题专栏 | 面试必备算法 | 面试高频算法
越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
作者简介:硕风和炜,CSDN-Java领域新星创作者,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享
恭喜你发现一枚宝藏博主,赶快收入囊中吧
人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?
算法题 |
大家再看这道题目之前,可以先去看一下我之前写过的一篇关于最长递增子序列算法题的博客,再看这个题目就更容易理解了。
博客的地址放到这里了,可以先去学习一下这到题目。
给定数组 arr ,设长度为 n ,输出 arr 的最长上升子序列。(如果有多个答案,请输出其中 按数值(注:区别于按单个字符的ASCII码值)进行比较的 字典序最小的那个)
数据范围:
0≤n≤200000,0≤arr[i]≤1000000000
要求:空间复杂度 O(n),时间复杂度 O(nlogn)
输入:
[1,2,8,6,4]
返回值:
[1,2,4]
说明:
其最长递增子序列有3个,(1,2,8)、(1,2,6)、(1,2,4)其中第三个 按数值进行比较的字典序 最小,故答案为(1,2,4)
import java.util.*;
public class Solution {
/**
* retrun the longest increasing subsequence
* @param arr int整型一维数组 the array
* @return int整型一维数组
*/
public int[] LIS (int[] arr) {
int n=arr.length;
// dp 数组中存储的是单调递增的元素
int[] dp=new int[n];
int cnt=0;
// len 数组表示以i位置结尾的最长递增子序列的长度
int[] len=new int[n];
for(int i=0;i<n;i++){
int x=arr[i];
int left=-1,right=cnt;
while(left+1<right){
int mid=(left+right)>>1;
if(dp[mid]<x){
left=mid;
}else{
right=mid;
}
}
dp[right]=x;
// 记录当前i位置下标最长递增子序列的长度 长度要加1,下标从0开始
len[i]=right+1;
if(right==cnt) cnt++;
}
// 收集答案
int[] ans=new int[cnt];
for(int i=n-1;i>=0;i--){
if(len[i]==cnt){
ans[--cnt]=arr[i];
}
}
return ans;
}
}
最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉! |