本期任务:介绍算法中关于动态规划思想的几个经典问题
【算法】【动态规划篇】第1节:0-1揹包问题
【算法】【动态规划篇】第2节:数字矩阵问题
【算法】【动态规划篇】第3节:数字三角形问题
【算法】【动态规划篇】第4节:硬币找零问题
【算法】【动态规划篇】第5节:剪绳子问题
【算法】【动态规划篇】第6节:最低票价问题
【算法】【动态规划篇】第7节:最长子串问题
【算法】【动态规划篇】第8节:最大正方形问题
【算法】【动态规划篇】第9节:乘积最大子数组问题
【算法】【动态规划篇】第10节:最长连续序列问题
问题来源
128. 最长连续序列
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
大佬解析
-
【动态规划】Python 题解
- 用哈希表存储每个端点值对应连续区间的长度
- 若数已在哈希表中:跳过不做处理
- 若是新数加入:
- 取出其左右相邻数已有的连续区间长度 left 和 right
- 计算当前数的区间长度为:cur_length = left + right + 1
- 根据 cur_length 更新最大长度 max_length 的值
- 更新区间两端点的长度值
代码
"""
需求:
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
思想:
多趟遍历法:(内存溢出)
第一趟,找出数组中的最大和最小元素max_num、min_num,初始化数组,值为0,[min_num, max_num]
第二趟,将出现过的位置置为1
第三趟,找出最长连续子序列
动态规划法:
出于内存考虑,建一个dp_dict,用于存储以某个点为端点的最长连续子串长度
维护一个最大长度值,遍历每个数字,最终得到最终结果
"""
class Solution:
def longestConsecutive(self, nums) -> int:
nums = set(nums)
size = len(nums)
if size in [0, 1]:
return size
hash_dict = dict()
max_length = 0
for num in nums:
left = hash_dict.get(num - 1, 0)
right = hash_dict.get(num + 1, 0)
cur_length = left + right + 1
max_length = max(max_length, cur_length)
hash_dict[num] = cur_length
hash_dict[num - left] = cur_length
hash_dict[num + right] = cur_length
return max_length
def longestConsecutive1(self, nums) -> int:
"""三趟遍历:内存溢出"""
size = len(nums)
if size in [0, 1]:
return size
min_num, max_num = min(nums), max(nums)
res = [0] * (max_num - min_num + 1)
for v in nums:
res[v - min_num] = 1
max_length = 0
tmp = list()
for i, v in enumerate(res):
if v == 0:
max_length = max(len(tmp), max_length)
tmp = list()
elif v == 1:
tmp.append(i + min_num)
max_length = max(len(tmp), max_length)
return max_length