91. 解码方法-数字-字母

image.pngimage.png

DFS

  1. class Solution:
  2. def numDecodings(self, s: str) -> int:
  3. def dfs(i):
  4. if i>=len(s):
  5. return 1
  6. ans=0
  7. if i+2<=len(s):
  8. num=int(s[i:i+2])
  9. if num>=10 and num<=26:
  10. ans+=dfs(i+2)
  11. if s[i]!='0':
  12. # print(ans)
  13. ans+=dfs(i+1)
  14. return ans
  15. if len(s)==0 or s[0]=="0":
  16. return 0
  17. else:
  18. return dfs(0)

DP

  1. class Solution:
  2. def numDecodings(self, s: str) -> int:
  3. n = len(s)
  4. s = ' ' + s
  5. f = [0] * (n + 1)
  6. f[0] = 1
  7. for i in range(1,n + 1):
  8. a = ord(s[i]) - ord('0')
  9. b = ( ord(s[i - 1]) - ord('0') ) * 10 + ord(s[i]) - ord('0')
  10. if 1 <= a <= 9:
  11. f[i] = f[i - 1]
  12. if 10 <= b <= 26:
  13. f[i] += f[i - 2]
  14. return f[n]

image.png

  1. class Solution:
  2. def numDecodings(self, s: str) -> int:
  3. n = len(s)
  4. s = ' ' + s
  5. f = [0] * 3
  6. f[0] = 1
  7. for i in range(1,n + 1):
  8. f[i % 3] = 0
  9. a = ord(s[i]) - ord('0')
  10. b = ( ord(s[i - 1]) - ord('0') ) * 10 + ord(s[i]) - ord('0')
  11. if 1 <= a <= 9:
  12. f[i % 3] = f[(i - 1) % 3]
  13. if 10 <= b <= 26:
  14. f[i % 3] += f[(i - 2) % 3]
  15. return f[n % 3]

剑指 Offer 14- I. 剪绳子image.png

(1)DFS超时

  1. class Solution:
  2. def cuttingRope(self, n: int) -> int:
  3. def dfs(chengji,changdu):
  4. if changdu==n:
  5. ans.append(chengji)
  6. if changdu<n:
  7. for j in range(1,n):
  8. dfs(chengji*j,changdu+j)
  9. ans=[]
  10. dfs(1,0)
  11. # print(ans)
  12. return max(ans)

(2)动态规划

image.png

  1. class Solution:
  2. def cuttingRope(self, n: int) -> int:
  3. dp = [0] * (n + 1)
  4. dp[2] = 1
  5. for i in range(3, n + 1):
  6. for j in range(2, 4):
  7. dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
  8. return dp[n]

一维DP - 图8
Python 代码(第三栏): 由于语言特性,理论上 Python 中的变量取值范围由系统内存大小决定(无限大),因此在 Python 中其实不用考虑大数越界问题。

打家劫舍问题

1、相邻不能偷 198

一维DP - 图9
一维DP - 图10
大佬的解

  1. class Solution:
  2. def rob(self, nums: List[int]) -> int:
  3. cur, pre = 0, 0
  4. for num in nums:
  5. cur, pre = max(pre + num, cur), cur
  6. return cur

自己的解

  1. class Solution:
  2. def rob(self, nums: List[int]) -> int:
  3. dp = [0]*len(nums)
  4. if len(nums)<=2:
  5. return max(nums)
  6. dp[0]=nums[0]
  7. dp[1]=max(nums[0],nums[1]) # 注意
  8. for i in range(2,len(nums)):
  9. dp[i]=max(dp[i-1],dp[i-2]+nums[i])
  10. return dp[-1]

2、头尾不能一起偷 213

一维DP - 图11

  1. class Solution:
  2. def rob(self, nums: [int]) -> int:
  3. def my_rob(nums):
  4. cur, pre = 0, 0
  5. for num in nums:
  6. cur, pre = max(pre + num, cur), cur
  7. return cur
  8. return max(my_rob(nums[:-1]),my_rob(nums[1:])) if len(nums) != 1 else nums[0]

×3、树形DP

  1. # Definition for a binary tree node.
  2. # class TreeNode:
  3. # def __init__(self, val=0, left=None, right=None):
  4. # self.val = val
  5. # self.left = left
  6. # self.right = right
  7. class Solution:
  8. def rob(self, root: TreeNode) -> int:
  9. def _rob(root):
  10. if not root: return 0, 0 # 偷,不偷
  11. left = _rob(root.left)
  12. right = _rob(root.right)
  13. # 偷当前节点, 则左右子树都不能偷
  14. v1 = root.val + left[1] + right[1]
  15. # 不偷当前节点, 则取左右子树中最大的值
  16. v2 = max(left) + max(right)
  17. return v1, v2
  18. return max(_rob(root))