给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],
它的长度是 4。
说明:
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
思路:在java代码里面
代码:
// class Solution {
// //套路(自顶向下)
// //去用于
// //改非递归(自底向上)
// public static int[] f = new int[10000];
// public static int[] p = new int[10000];
// public static int n;
// public static int robot(int idx,int[] nums){
// if (idx < 0){
// return 0;
// }
// if(f[idx] > 0){
// return f[idx];
// }
// int ans = 0;
// for (int i = 0; i < idx ;i++){
// if(nums[idx] > nums[i]){
// ans = Math.max(ans,robot(i,nums));
// }
// }
// f[idx] = ans + 1;
// return ans +1;
// }
// public int lengthOfLIS(int[] nums) {
// for(int i = 0;i<10000;i++){
// f[i] =0;
// }
// n = nums.length;
// for(int i = 0;i< n;i++){
// p[i] = nums[i];
// }
// p[n] = 1000000000;
// n++;
// for(int idx = 0;idx < n;idx++){
// int ans = 0;
// for (int i = 0; i < idx ;i++){
// if(p[idx] > p[i]){
// ans = Math.max(ans,f[i]);
// }
// }
// f[idx] = ans + 1;
// }
// return f[n-1] -1;
// }
// }
// class Solution {
// public int lengthOfLIS(int[] nums) {
// if(nums.length<1) return 0;
// //存储,以 i 元素结尾的最长公共子序列长度
// int[] deep = new int[nums.length];
// deep[0] = 1;
// int res = 1;
// //遍历元素,向后迭代,动态规划
// for(int i=1;i i-1
// for(int j=0;j tails[len]){
tails[++len] = nums[i];
} else {
// 如果在中间,则二分搜索
tails[binarySearch(tails, 0, len, nums[i])] = nums[i];
}
}
return len + 1;
}
private int binarySearch(int[] tails, int min, int max, int target){
while(min <= max){
int mid = min + (max - min) / 2;
if(tails[mid] == target){
return mid;
}
if(tails[mid] < target){
min = mid + 1;
}
if(tails[mid] > target){
max = mid - 1;
}
}
return min;
}
}
python版:
class Solution:
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
#可用使用动态规划,用数组res[i]表示到i 时的最长上升序列数,取在i前面比num[i]小的数的最长在上升序列来更新res[i],所以时间复杂度为 O(n2)。
if nums == []:
return 0
tail = []
tail.append(nums[0]) #tail表示最长升序列的长度为i的最后一个数字
maxlen = 0 #定义tail的下标也就是最长升序列的长度-1
for i in range(len(nums)):#遍历nums数组
if nums[i] > tail[maxlen]: #如果nums数组比当前的最长升序列的最后一位数字大,那么就添加进去
tail.append(nums[i])
maxlen += 1
else:
#就进行二分查找,找到tail数组中
left,right = 0,maxlen
while left <= right:
mid = (left + right) // 2
if tail[mid] < nums[i]:
left = mid + 1
else:
right = mid - 1
tail[left] = nums[i]
return maxlen+ 1