题解 | #最长递增子序列#
最长递增子序列
http://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481
(python版本!)
刚开始用的动态规划的解法,虽然超时了,但是自己写出来了很开心!!!
class Solution:
def LIS(self , arr ):
def func1(li):
return len(li)
def func2(li):
return ''.join(list(map(str,li)))
res=[[arr[i]] for i in range(len(arr))] #res[i]表示以arr[i]为结尾的最长递增子序列的元素集合
for i in range(1,len(arr)):
for j in range(i):
if(arr[j]<arr[i]):
if(len(res[j])+1>len(res[i])):
temp=list(res[j])
temp.append(arr[i])
res[i]=temp
elif(len(res[j])+1==len(res[i])): #如果相等则比较字典序
temp=list(res[j])
temp.append(arr[i])
str_j=''.join(list(map(str,temp)))
str_i=''.join(list(map(str,res[i])))
if(str_j<str_i):
res[i]=temp
print(res)
anses=[]
max_len=len(max(res,key=func1))
for i in range(len(res)):
if(len(res[i])==max_len):
anses.append(res[i])
ans=min(anses,key=func2)
return ans
arr=[2,1,5,3,6,4,8,9,7]
res=Solution().LIS(arr)
print(res)于是又看了大佬们的解析,根据面向测试用例编程,写出来了贪心+二分的解法!
class Solution:
def LIS(self,arr):
max_len=[1]*len(arr) #max_len[i]表示以arr[i]为结尾的最长递增子序列的长度
vec=[]
#vec存放递增子序列,vec的长度即使最长递增子序列的长度但并不一定是答案
#如果arr[i]>vec[-1],直接添加arr[i];否则在vec中寻找第一个比arr[i]大的元素,替换之
vec.append(arr[0])
for i in range(1,len(arr)):
if(arr[i]>vec[-1]):
vec.append(arr[i])
max_len[i]=len(vec)
elif(arr[i]<=vec[-1]):
#调用二分搜索寻找第一个比arr[i]大的元素
idx=self.binary_search(vec,arr[i])
vec[idx]=arr[i]
max_len[i]=idx+1
print(max_len)
len_vec=len(vec)
res=[0]*len_vec
for i in range(len(max_len)-1,-1,-1):
if(max_len[i]==len_vec):
res[len_vec-1]=arr[i]
len_vec-=1
return res
def binary_search(self,vec,x):
#寻找第一个比x大于等于的元素,仅适用于本题,x<vec[-1]的情况。
left=0
right=len(vec)-1
while(left<=right):
mid = left + (right - left) // 2
if(x==vec[mid]):
return mid
elif(x<vec[mid]):
right=mid-1
elif(x>vec[mid]):
left=mid+1
return left
if(__name__=='__main__'):
#line=list(map(int,input().strip().split()))
line=[1,3,8,6,5,2,5]
res=Solution().LIS(line)
print(res)
三奇智元机器人科技有限公司公司福利 82人发布
