剑指offer 46-48题 python题解记录

题46:把数字翻译成字符串

啊啊啊终于会用dp了,向前迈了一步,奶思!!
和青蛙跳是一个思路,转移方程:
dp[i] = dp[i-1] #当前数字单独翻译为一个字母(0<=val<=9)
dp[i]+=dp[i-2] if s[i-1]+s[i] 可以翻译成一种字母 (10<=加起来val<=26)
我将dp[0]、dp[1]都初始化了,王先生的题解没有

class Solution:
    def translateNum(self, num: int) -> int:
        if num<10:
            return 1
        num=str(num)
        dp=[0]*len(num)
        dp[0]=1
        dp[1]=2 if '0'<=num[:2]<='25' else 1
        for i in range(2,len(num)):
            dp[i]+=dp[i-1]
            if '10'<=num[i-1:i+1]<='25':
                dp[i]+=dp[i-2]
        return dp[-1]

题47:礼物的最大价值

还是dp,但我想的是记录每一步的dp,这样得出来的是局部最优(本质是贪心了),正解是记录第i行第j列的最大值,设置dp的维度为m*n。
另一个小技巧是,用dp[i][j]记录grid[i-1][j-1]可以解决初始化问题,也不会出现无法处理一维数据的问题。

class Solution:
    ### dp
    def maxValue(self, grid: List[List[int]]) -> int:
        m,n=len(grid),len(grid[0])
        dp=[[0]*(n+1) for _ in range(m+1)]
        for i in range(1,m+1):
            for j in range(1,n+1):
                dp[i][j]=grid[i-1][j-1]+max(dp[i-1][j],dp[i][j-1])
        return dp[-1][-1]

题48:最长不含重复字符的子字符串

不要一上来就遍历,也该学会分析特点和规律了
不含重复字符的子串怎么找呢?
若含有重复字符做头尾,去掉尾巴,就是不含重复字符的子串了。
若不含重复字符,则从头到尾就是子串。
因此,用字典记录字符上一次出现的位置,用st记录当前最长子串的起始,这样只需一次遍历

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        dct,ans,st={
     },0,0
        for i in range(len(s)):
            if s[i] in dct.keys() and dct[s[i]]>=st:
                st=dct[s[i]]+1
            dct[s[i]]=i
            ans=max(ans,i-st+1)
        return ans

你可能感兴趣的:(编程题)