经典子序列问题
最长递增子序列问题
给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)
例如:给定一个长度为8的数组A{1,3,5,2,4,6,7,8},则其最长的单调递增子序列为{1,2,4,6,7,8},长度为6.
def solution(num):
dp = [1]*len(num)//初始化为1
for i in range(len(num)):
for j in range(i):
if num[j]<num[i] and dp[i]<dp[j]+1://序号在i前面且小于s[i],且比之前记录的个数大
dp[i] = dp[j]+1
return dp//返回当前记录的子序列长度
//若需输出子序列
//考虑用字典记录序列号与值,遍历dp,后面会覆盖前面的
d = {}
for i in range(len(dp)):
d[dp[i]] = num[i]
//遍历子序列
for i in range(1,dp[-1]+1):
print(d[i])
最长连续序列
给定一个未排序的整数数组,找出最长连续序列的长度
输入[100,4,200,1,3,2]
输出 4,[1,2,3,4]
- 遍历数组nums,每个数都放到map,value为1
- 遍历数组nums,递归查找数num的前一个数,找到就修改map中的value,不存在返回0,存在且大于1则直接返回
- 遍历map,找到最大的value,返回即最长连续序列的长度
def forward(num,d)://向前寻找
if num not in d:
return 0
else:
if d[num]>1://之前已经找过
return d[num]
else:
d[num] = forward(num-1,d)+1//基础上+1
return d[num]
def solution(nums):
d = {}
for i in nums://存入字典
d[i] = 1
for i in nums:
d[i] = forward(i-1,d)+1//向前找
maxValue = 0//记录最大值
for k,v in d.items()://遍历字典
maxValue = max(maxValue,v)
print(d)
print(maxValue)
nums = [100,4,200,1,3,2]
solution(nums)
未排序数组中累加和为给定值的最长子数组
题:给定一个数组arr,和一个整数num,求在arr中,累加和为等于num的最长子数组的长度
如:arr= [7,3,2,1,1,7,7,7],num = 7
返回[3,2,1,1],4
思路:
-
设置变量sumVal = 0,表示从0位置开始一直加到i位置所有元素的和
-
设置变量maxLen = 0,表示累加和为k的最长子数组长度
-
设置hashmap,key便是从arr最左边开始累加过程中出现过的值,value则表示sumVal最早出现的值
-
从左遍历,令sumVal +=arr[i]
- map中查看是否存在sumVal-k
- 如果存在,取出sumVal对应的value,maxLen = max(maxLen,i-d[sumVal-k]),更新len
-
检查当前的sumVal是否存在map,不存在则记录进字典,存在即忽略,只记录第一次出现的值
-
继续遍历,遍历结束,返回maxLen即结果
def solution(nums,k):
d = {}
sumVal = 0
maxLen = 0
for i in range(len(nums)):
sumVal+=nums[i]
if (sumVal-k) in d:
maxLen = max(maxLen,i-d[sumVal-k])
if sumVal not in d:
d[sumVal] = i
print(maxLen)
nums = [7,3,2,1,1,7,7,7]
solution(nums,7)
最长无重复子串
def solution(s):
max_len = 0
substr = []
for i in range(len(s)):
if s[i] not in substr:
substr.append(s[i])
if res<len(substr)://更新长度
res = len(substr)
max_str = ''.join(substr)
else:
index = substr.index(s[i])//找到重复点索引
substr = substr[index+1:]//去掉之前的部分
substr.append(s[i])//加上当前节点
return max_str