代码:
class Solution {
public int lengthOfLIS(int[] nums) {
int[]tails=new int[nums.length];
int size=0;
for(int n:nums){
int pos=binarySearchLarger(tails,n,size);
if(pos==-1){
pos=size;
}
tails[pos]=n;
if(pos==size){
size++;
}
}
return size;
}
//find the first tail >= num
private int binarySearchLarger(int[]arr,int target,int end){
int left=0;
int right=end;
while(left<right-1){
int mid=left+(right-left)/2;
if(arr[mid]>=target){
right=mid;
}else{
left=mid;
}
}
if(arr[left]>=target){
return left;
}
if(arr[right]>=target){
return right;
}
return -1;
}
}
tails[i]
存储的是长度为i+1
的LIS末尾元素最小值,size
为当前记录到的最长的LIS长度,用于binary search时确定搜索范围,搜索结果反过来决定size
要不要扩大。
输入数组元素挨个进行检验,当前元素n
是否能够扩充到某个LIS后面,即替换已有的某个长度的LIS末尾元素(第一个使tails[pos]>=n
的pos
,用binary search搜索),使该长度的LIS具有更高的可扩展性;如果n
比当前所有LIS末尾元素都大(即binary search没找到合法的位置,返回pos=-1
时;或者初始条件size=0
,更新tails[0]
时),size
就可以加一了。
n
替换第一个tails[pos]>=n
的原因:已经比n
小的,不需要替换;如果tails[pos]
不是第一个大于等于n
的,也就是说必然存在tails[pos-1]>=n
,必然存在以tails[pos]
为末尾元素的IS:[a,...b,c,tails[pos]]
,c=tails[pos-1]>=n
,则n
无法替代tails[pos]
与之前的元素组成IS。