题目1:
找出一个字符序列中一个最长的包含不重复字符的子字符串,计算该最长子字符串的长度。比如在字符串“arabcacfr”中,最长的不含重复字符的子字符串是“acfr”,长度为4。
分析:
找最长优先考虑使用动态规划来解题
动态规划:
待求问题划分为若干个子问题(阶段),按顺序求解子问题,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些可能达到最优的局部解,依次解决各阶段,最后一个子阶段就是初始问题的解。
定义状态转移函数:f(i)
定义函数f(i)为第i个字符为结尾的不包含重复字符的自字符串的子字符串的最长长度,假设我们知道了f(i-1),如果第i个字符在前面没有出现过,则f(i)=f(i-1)+1,
如果第i个字符在前面出现过,d表示第i个字符与它最近一次出现的索引的间隔
如果d<=f(i-1),f(i)=d 表示第i个字符出现两次所夹的子字符串中再也没有其他重复的字符了。
d>f(i-1) f(i)=f(i-1)+1 表示,即使前面出现了,但出现在f(i-1)的最长子字符串之前
正向求解:
“arabcacfr”
f(0)=1 f(1)=f(0)+1
f(2)=2-0=2 f(3)=f(2)+1=3
f(4)=f(3)+1=4 f(5)=3
f(6)=2 f(7)=3
f(8)=4
代码实现:
def longSubstringWithoutDuplication(s):
if len(s)==0 or len(s)==1:
return len(s)
curlength=0
maxlength=0
dic={} # 存放每一个字符最后一次出现的索引
for i in range(len(s)):
# 前面没有出现过,或者出现过,间隔大于前一个字符中最大无重复字符串
if s[i] not in dic or i-dic[s[i]]>curlength:
curlength += 1
else:# 前面出现了,间隔小于前一个字符中最大无重复字符串
curlength = i-dic[s[i]]
dic[s[i]]=i
maxlength=max(curlength,maxlength)
return maxlength
if __name__ == '__main__':
s='arabcacfr'
s1='abcabcbb'
s2='a'
print(longSubstringWithoutDuplication(s2))
题目2:
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m]。请问k[0]xk[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案。
示例1
输出
复制18
思路:
正向求解,使用products数组存放当前数字的最大乘积值,f(n) = max(f(i)*f(n-i))
动态规划Python代码
1 # -*- coding:utf-8 -*-
2 class Solution:
3 def cutRope(self, number):
4 # write code here
5 if number < 2:
6 return 0
7 if number == 2:
8 return 1
9 if number == 3:
10 return 2
11 # 动态规划,正向求解,max(f(i)*f(n-i))
12 products = [0] * (number+1) #多了索引0
13 products[1] = 1
14 products[2] = 2
15 products[3] = 3
16 for i in range(4, number+1, 1): # 左闭右开
17 max_pro_i = 0
18 for j in range(1, (i/2)+1, 1):
19 # 找i的最大乘积
20 if max_pro_i < products[j] * products[i - j]:
21 max_pro_i = products[j] * products[i - j]
22 products[i] = max_pro_i
23 return products[-1]