爽歪歪666
不以物喜,不以己悲,努力才是永恒的主题。

题目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

输入

复制
8

输出

复制
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]

 

posted on 2020-04-15 18:01  爽歪歪666  阅读(296)  评论(0编辑  收藏  举报