题目描述
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
解题思路
动态规划
这里参考官方题解,https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-by-leetcode-soluti/,官方有动态图解
class Solution: def lengthOfLIS(self, nums): if not nums: return 0 dp = [] for i in range(len(nums)): dp.append(1) for j in range(i): if nums[i] > nums[j]: dp[i] = max(dp[i], dp[j] + 1) return max(dp) S = Solution() print(S.lengthOfLIS([10, 9, 2, 5, 3, 7, 101]))
二分加贪心
首先设置一个d列表,首先第一个元素直接加入,d = [0], 对于第二个元素8,由于他大于d[-1],所以直接加进去,d = [0, 8], 对于第三个元素4,由于4比8小,所以使用二分查找来找出替换的位置并进行替换
以输入序列 [0,8,4,12,2]为例:
第一步插入 0,d=[0];
第二步插入 8,d=[0,8];
第三步插入 4,d=[0,4];
第四步插入 12,d=[0,4,12];
第五步插入 2,d=[0,2,12]。
class Solution: def lengthOfLIS(self, nums): d = [] for i in nums: if not d or d[-1] < i: d.append(i) else: l, r = 0, len(d) - 1 loc = r while l <= r: mid = (l + r) // 2 if d[mid] >= i: loc = mid r = mid - 1 else: l = mid + 1 d[loc] = i return d S = Solution() print(S.lengthOfLIS([10, 9, 2, 5, 3, 7, 101]))