示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4.
class Solution: def lengthOfLIS(self, nums) -> int: length = len(nums) new_arr = [] # 最长上升子列数组 if length == 0: # 原数组为空 return 0 elif length == 1: # 原数组只有一个元素 return 1 else: new_arr.append(nums[0]) for i in range(1, length): if nums[i] <= new_arr[0]: # 若是遍历的元素比子列中最小值还小或相等,则替换 new_arr[0] = nums[i] elif (new_arr[0] < nums[i]) and (nums[i] <= new_arr[-1]): # 若是遍历的元素值大小在子列中间,则查找到第一个大于或等于此元素的子列元素,进行替换;new_arr目前是已经有序的,因此能够用二分查找提升检索效率 low,high = 0,len(new_arr)-1 while low <= high: mid = (low+high)//2 if new_arr[mid] >= nums[i]: new_arr[mid] = nums[i] break else: low = mid + 1 elif nums[i] > new_arr[-1]: # 若是遍历的元素比子列最大元素还大,则追加到子列尾部 new_arr.append(nums[i]) return len(new_arr)
执行用时 : 52 ms, 在Longest Increasing Subsequence的Python3提交中击败了96.97% 的用户 内存消耗 : 13.1 MB, 在Longest Increasing Subsequence的Python3提交中击败了96.54% 的用户java
import java.util.ArrayList; import java.util.Scanner; import java.util.List; public class SubSequence { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] s = new int[n]; for(int i=0; i<n; i++){ s[i] = sc.nextInt(); } int max_len = getSubSequenceLen(n, s); System.out.println("最长递增子序列长度:"+max_len); } public static int getSubSequenceLen(int n, int[] s){ int[] liss = new int[n]; // 以各元素结尾的最长递增子序列长度 int[] pre = new int[n]; // 以各元素结尾的最长递增子序列的当前元素的前向元素 List<Integer> maxSubSequence = new ArrayList<Integer>(); int max_len = 1; // 最长递增子序列长度 int end_index = 0; // 长递增子序列尾元素地址 // 初始化 for(int i=0; i<n; i++){ liss[i] = 1; pre[i] = s[i]; } for(int p=1; p<n; p++){ for(int q=0; q<p; q++){ if(s[q]<s[p] && liss[q]+1>liss[p]){ liss[p] = liss[q]+1; pre[p] = s[q]; end_index = p; } } if(max_len<liss[p]){ max_len = liss[p]; maxSubSequence.add(pre[p]); // 将最长递增子序列中当前元素的前向元素添加进来 } } maxSubSequence.add(s[end_index]); // 将最长递增子序列的尾元素添加进来 System.out.println("最长递增子序列:"+maxSubSequence); return max_len; } }