https://leetcode.com/problems/longest-increasing-subsequence/
思路1 n^2
参考http://bookshadow.com/weblog/2015/11/03/leetcode-longest-increasing-subsequence/
动态规划(Dynamic Programming)
状态转移方程:
dp[x] = max(dp[x], dp[y] + 1) 其中 y < x 并且 nums[x] > nums[y]
即在求dp[x]的时候,比较x之前的元素y以及其对应的dp[y], 找到一个最大的dp[y] + 1, y
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
size = len(nums)
dp = [1] * size
for x in range(size):
for y in range(x):
if nums[x] > nums[y]:
dp[x] = max(dp[x], dp[y] + 1)
return max(dp) if dp else 0
思路2 nlogn
binary search
这里类似于插入排序,这里用BS不是找到一个target数的index,而是找到一个target所能插入的index。所以不返回mid, 返回low,并且也不用对等号进行判断。
就是用dp数组来维护一个升序数组,scan每一个数组值A[i],然后看A[i]是否能插入dp中,如果low >=len(dp), 那么就在dp末尾append; else 则替换dp[low] = A[i],因为这样替换并没有降低当前LIS的长度,并且还扩大increasing subsequence长度的增长空间
本质就是如果是个可以插入的值,例如dp = {2, 5}, A[i] = 3, 则替换最后一个值,降低increasing subsequence的最大值以扩大increasing subsequence长度的增长空间;如果A[i] = 6, 无法插入,那么就直接加入在dp末尾就行。这里如果只对,low>=len(dp)在dp末尾append,那么就不能修改搜索递增序列的最小值,使得[10,9,2,5,3,7,101,18]这样的输入,得到的结果是[10, 101]
这是一个trick。记住
code 参考 http://bookshadow.com/weblog/2015/11/03/leetcode-longest-increasing-subsequence/
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
size = len(nums)
dp = []
for x in range(size):
low, high = 0, len(dp) - 1
while low <= high:
mid = (low + high) / 2
if dp[mid] >= nums[x]:
high = mid - 1
else:
low = mid + 1
if low >= len(dp):
dp.append(nums[x])
else:#这里在dp = [2,3], nums[x] = 1的情况下,会将dp变成[1,3], 虽然不是递增的seq,但是长度一样。
dp[low] = nums[x]
return len(dp)
自己重写code
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 0: return 0
lis = []
for i in xrange(len(nums)):
if lis == []:
lis.append(nums[i])
else:
low, high = 0, len(lis) - 1
while low <= high:
mid = (low + high) / 2
if lis[mid] < nums[i]:#这里不要有等号
low = mid + 1
else:#等号放在这里,因为lis = [2], nums[i] = [2],这样的case不应该变成[2,2]
high = mid - 1
if low == len(lis):#不是low == i
lis.append(nums[i])
else:
lis[low] = nums[i]
return len(lis)