leetcode -- Longest Increasing Subsequence -- DP 重点常考
2015-12-14 18:01
597 查看
https://leetcode.com/problems/longest-increasing-subsequence/
动态规划(Dynamic Programming)
状态转移方程:
即在求dp[x]的时候,比较x之前的元素y以及其对应的dp[y], 找到一个最大的dp[y] + 1, y
这里类似于插入排序,这里用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/
思路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)
相关文章推荐
- UINavigationBar和UINavigationItem的区别和联系
- __builtin_expect 解惑
- iOS摄像头和相册-UIImagePickerController-浅析
- [UE4]手动指定模型的材质资源文件路径(骨骼、材质、动画)
- 获取版本号和build号
- 自定义UINavigationItem的两种方法以及相应的隐藏方法
- Sqoop Developer’s Guide v1.4.6 (Sqoop开发者指南,中文版)
- iOS-UILabel的宽度自适应文字
- ZnDuiDesigner 版本更新
- 蓝牙BR/EDR和Bluetooth Smart的十大重要区别
- Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:]
- UICollectionView的简单使用(一)
- Leetcode194: Range Sum Query 2D - Immutable
- openstack devstack tox ValueError: need more than 1 value to unpack
- iOS开发备忘录:自定义UINavigationBar背景图片和Back按钮
- uilabel的字体不一致
- LeetCode 300 Longest Increasing Subsequence
- django queryset values&values_list
- easyui dialog 引入jsp页面赋值
- Leetcode193: Range Sum Query - Immutable