给定数组 arr ,设长度为 n ,输出 arr 的最长上升子序列。(如果有多个答案,请输出其中 按数值(注:区别于按单个字符的ASCII码值)进行比较的 字典序最小的那个)
数据范围:
要求:空间复杂度 ,时间复杂度
[2,1,5,3,6,4,8,9,7]
[1,3,4,8,9]
[1,2,8,6,4]
[1,2,4]
其最长递增子序列有3个,(1,2,8)、(1,2,6)、(1,2,4)其中第三个 按数值进行比较的字典序 最小,故答案为(1,2,4)
from collections import defaultdict, deque import bisect import math import itertools Yes, No = "Yes", "No" YES, NO = "YES", "NO" mod = int(1e9 + 7) class Solution: def LIS(self, ls): n = len(ls) # 当前下标的最长长度 len_ls = [0] * n # 构造数组 inc_ls = [] # 正常添加达到的长度 seq_len = 0 # 结果记录 max_length = 0 for i in range(len(ls)): cur = ls[i] j = bisect.bisect_left(inc_ls, cur) if j == len(inc_ls): # cur应该插入到最后面则append inc_ls.append(cur) seq_len += 1 len_ls[i] = seq_len else: inc_ls[j] = cur len_ls[i] = j + 1 max_length = max(max_length, len_ls[i]) # 构造结果 长度为max_length res = [0] * max_length for i in range(len(ls) - 1, -1, -1): if len_ls[i] == max_length: res[max_length - 1] = ls[i] max_length -= 1 return res
import bisect class Solution: def LIS(self , arr ): dp, m = [], [] for i, x in enumerate(arr): if not m or x > m[-1]: m.append(x) dp.append(len(m)) else: idx = bisect.bisect_left(m, x) m[idx] = x dp.append(idx + 1) cur = len(m) - 1 ans = [0] * len(m) for i, x in enumerate(reversed(dp)): if x == cur + 1: ans[cur] = arr[-i-1] cur -= 1 return ans
# # retrun the longest increasing subsequence # @param arr int整型一维数组 the array # @return int整型一维数组 # class Solution: def LIS(self , arr ): # write code here res=[] maxlen=[] if not arr: return res res.append(arr[0]) maxlen.append(1) for i in range(1,len(arr)): if arr[i]>res[-1]: res.append(arr[i]) maxlen.append(len(res)) else: last=len(res)-1 first=0 mid=(last+first)/2 pos=-1 while res[mid]!=arr[i]: mid=(last+first)/2 if res[mid]==arr[i]: pos=mid break elif first<=last and res[mid]>arr[i]: if mid==0&nbs***bsp;res[mid-1]<=arr[i]: pos=mid break else: last=mid-1 else: first=mid+1 if pos!=-1: res[pos]=arr[i] maxlen.append(pos+1) j=len(res) i=len(arr)-1 while j>0: if maxlen[i]==j: j-=1 res[j]=arr[i] i-=1 return res
class Solution: def LIS(self, arr): n = len(arr) m = [0] * n for x in range(n - 2, -1, -1): for y in range(n - 1, x, -1): if arr[x] < arr[y] and m[x] <= m[y]: m[x] += 1 max_value = max(m) result = [] for i in range(n): if m[i] == max_value: result.append(arr[i]) max_value -= 1 return result
参考kite97大佬的代码,python实现:
# # retrun the longest increasing subsequence # @param arr int整型一维数组 the array # @return int整型一维数组 # class Solution: def LIS(self, arr): if arr is None or len(arr) == 0: return [] res = [arr[0]] temp = [1] # 每个位置为终点的LIS长度 for i in range(1, len(arr)): if arr[i] > res[-1]: res.append(arr[i]) temp.append(len(res)) else: low, high = 0, len(res) while low < high: mid = (high - low) // 2 + low if res[mid] >= arr[i]: high = mid else: low = mid + 1 res[low] = arr[i] temp.append(low + 1) i = len(arr) - 1 k = len(res) - 1 while k >= 0: if temp[i] - 1 == k: res[k] = arr[i] k -= 1 i -= 1 return res