题目一:(求最长相同字母)
给定一组字符串,包含大小写字母,求由同一字母组成的最长子串,字母不区分大小写。
例如:aAbbBBcccCC 最长子串:cccCC
例如:ddddDDDDeeeEEEeeeEEEeee 最长子串:eeeEEEeeeEEEeee
状态定义:dp[i]为以i为结尾的相同字母子串的长度
以字符串 "aAbbBBcc" 为例, 看状态变化.
字符串 a A b b B B c c
状态值 1 2 1 2 3 4 1 2
得出状态转移方程为:
if s[i] == s[i-1]: dp[i] = dp[i-1] + 1
if s[i] != s[i-1]: dp[i] = 1
python代码如下:
def longestSameChars(s):
if s == None : return None
w = len(s)
if w == 0 or w == 1 : return s
dp = [ 1 for i in range(w) ]
for i in range(1, w):
if s[i].upper() == s[i-1].upper() : dp[i] = dp[i-1] + 1
else : dp[i] = 1
# 以下求出最大的相同字符子串开始索引和结束索引
end, maxd = 0, 0
for i in range( len(dp) ):
if dp[i] > maxd:
maxd = dp[i]
end = i
sta = end - maxd + 1
return s[sta : end + 1 ]
题目二:(求最长连续上升子系列长度)
给定一个整数数组, 求数组当中的最长子串长度是多少?
例如: 1, 4, 3, 6 最长子串是 3 6 或者 1 4 长度都是2
例如: 15, 1, 5, 13, 6, 11, 7, 8 最长子串是 1, 5, 13 长度都是 3
状态定义:dp[i]为以i为结尾的最长子串长度.
以数组 [15, 1, 5, 13, 6, 11, 7, 8]为例, 看状态变化.
数组 15 1 5 13 6 11 7 8
状态 1 1 2 3 1 2 1 2 (最长连续上升子系列长度)
得出状态转移方程为:
if nums[i] > nums[i-1] : dp[i] = dp[i-1] + 1
if nums[i] <= nums[i-1]: dp[i] = 1
python 代码如下:
def lengthOfContinueLIS(nums):
if len(nums) == 0 : return 0
dp = [ 0 for i in range( len(nums) ) ]
for i in range( 1, len(nums) ):
if nums[i] > nums[i-1] : dp[i] = dp[i-1] + 1
else : dp[i] = 1
return max(dp)
题目三 :(求最长上升子系列长度)
给定一个整数数组, 求数组当中的最长上升子系列长度是多少?
例如: 1, 4, 3, 6 最长子串是1 3 6 或者 1 4 6 长度都是3
例如: 15, 1, 5, 13, 6, 11, 7, 8 最长上升子系列是 1, 5, 6, 7, 8 长度都是 5
状态定义:dp[i]为以i为结尾的最长上升子系列的长度.
以数组[10, 9, 2, 5, 3, 1, 7, 101, 18]为例,看状态的变化.
数组 10 9 2 5 3 1 7 101 18
状态 1 1 1 2 2 1 3 4 4 (最长上升子系列的长度)
当前索引i,找到一个i之前( 0 ~ i-1 )比i的值要小且dp值最大的值再+1
得出状态转移方程为:
for j in range( i ):
if nums[j] < nums[i] : dp[i] = max( dp[i], dp[j] + 1 )
python代码如下:
def lengthOfLIS(nums):
if len(nums) == 0 : return 0
dp = [ 1 for i in range( len(nums) ) ]
for i in range( 1, len(nums) ):
for j in range( i ):
if nums[j] < nums[i] : dp[i] = max( dp[i], dp[j] + 1 )
return max(dp)
题目四 : (求最长无重复字符子串的长度 )
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb” 输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb” 输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew” 输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
状态定义: dp[i]以i为结尾的最长无重复字符子串的长度
以字符串 "abcabcbb" 为例, 看状态变化.
字符 a b c a b c b b
状态 1 2 3 3 3 3 2 1 (最长无重复字符子串的长度)
状态转移方程:
for j in range( i - 1, -1, -1 ):
if s[i] != s[j] : dp[i] += 1
else : break
python代码如下:
def lenghtOfLongestSubstring(s):
if len(s) == 0 or len(s) == 1 : return len(s)
dp = [ 1 for i in range( len(s) ) ]
for i in range( 1 , len(s) ):
endfor = i - 1 - dp[i-1]
for j in range( i - 1, endfor, -1 ):
if s[i] != s[j] : dp[i] += 1
else : break
return max(dp)
题目五 :(求最长交替子系列长度)
一个系列,它的相邻数字的大小关系就是升序降序轮流交替的(最初可以是升序,也可以是降序),
就称为wiggle sequence.比如[ 1, 7, 4, 9, 2, 5, ]就是一个wiggle sequence.但是[ 1, 4, 7, 2, 5]
和[1, 7, 4, 5, 5]就不是. 给出一个数组,求出它的最长wiggle sequence子系列.
状态定义: dp[i]以i为结尾的最大摆动系列的长度
以数组[10, 9, 2, 5, 5, 1, 7, 11, 8]为例,看状态的变化.
数组 10 9 2 5 5 1 7 11 8
状态st 0 -1 -1 1 1 -1 1 1 -1 (状态st 保存[1:上升,-1:下降,0:相等]信息)
状态dp 1 2 2 3 3 4 5 5 6 (状态dp 最大摆动系列的长度)
状态转移方程(伪代码):
if nums[i] == nums[i-1] :
st[i], dp[i] = st[i-1], dp[i-1]
if nums[i] > nums[i-1]:
st[i] = 1
if st[i-1] == 1 : dp[i] = dp[i-1]
if st[i-1] == -1 : dp[i] = dp[i-1] + 1
if nums[i] < nums[i-1]:
st[i] = -1
if st[i-1] == -1 : dp[i] = dp[i-1]
if st[i-1] == 1 : dp[i] = dp[i-1] + 1
python代码如下:
def wiggleMaxLenght(nums):
if nums == None : return None
w = len(nums)
if w == 0 or w == 1 : return w
dp , st = [ 1 for i in range(w) ], [ 0 for i in range(w) ]
for i in range( 1, w ):
if nums[i] == nums[i-1] :
st[i], dp[i] = st[i-1], dp[i-1]
elif nums[i] > nums[i-1]:
st[i] = 1
dp[i] = dp[i-1] if st[i-1] == 1 else dp[i-1] + 1
else:
st[i] = -1
dp[i] = dp[i-1] if st[i-1] == -1 else dp[i-1] + 1
return dp[-1]