2022-4-25
70. Climbing Stairs
def climbStairs(n: int) -> int:
ans = [0] * (n + 1)
ans[0] = ans[1] = 1
for i in range(2, n + 1):
ans[i] = ans[i - 1] + ans[i - 2]
return ans[-1]
def climbStairs2(n: int) -> int:
step1, step2 = 1, 1
for i in range(2, n + 1):
tmp = step1 + step2
step1 = step2
step2 = tmp
return step2
746. Min Cost Climbing Stairs
def minCostClimbingStairs(cost: List[int]) -> int:
for index in range(2, len(cost)):
cost[index] += min(cost[index - 1], cost[index - 2])
return min(cost[-1], cost[-2])
198. House Robber
- 边界处理直接开了新的money list2333;之前做的一版对边界是单独处理的;
rob2
这里的思路实际上是考虑在Index位置的金额最大值取决于index-2及index-3的最大值,不需要考虑前述[:index-1](不包括Index-1)的情况,因为偷盗的金额是正数,假设我们在index时考虑index-4,它实际上是可以跳到index-2上再跳到index上,也就是说在考虑Index-2的时候就把index-4等考虑进去了!rob3
的思路【neetcode yyds】!妙哇!- 考虑每个房子,你有两种选择:偷或者不偷;ps:money[index]表示处于Index处当前偷的最大金额
- 假设你在房子n,你选择偷,那么当前的偷的总金额为房子n偷的加上房子1到n-2房子中偷得到最大值,即nums[n]+money[n-2] (注意这里后面可以简化);假设你现在不偷,那么当前你拥有的偷盗金额就是money[n-1]!【所以实际上我们只需要动态存储2个元素就够够了】
- 综上所述:money[n] = max(nums[n]+money[n-2], money[n-1])
- 当然可以考虑就地修改nums list不用开辟新的money list;
- 对比一下
rob2
中的money中的每位都是在考虑了在index时,偷了的情况下的最大偷盗金额;而rob3
是把在index下偷和不偷的状态一起考虑了~
def rob1(nums: List[int]) -> int:
if len(nums)==1: return nums[0]
if len(nums)==2: return max(nums[-1], nums[-2])
for i in range(2, len(nums)):
nums[i] = nums[i] + max(nums[0:i-1])
return max(nums[-1], nums[-2])
def rob2(nums: List[int]) -> int:
money = [0, 0, 0]
money.extend(nums)
for index in range(3, 3 + len(nums)):
money[index] = max(money[index - 2], money[index - 3]) + money[index]
return max(money[-1], money[-2])
def rob3(nums: List[int]) -> int:
rob1, rob2 = 0, 0
# [rob1, rob2, n, n+1, n+2, ...]
for num in nums:
tmp = max(num + rob1, rob2)
rob1 = rob2
rob2 = tmp
return rob2
213. House Robber II
- 本题很自然的一个思路就是复用House Robber的模块;区别是II在I的基础上加了一个限制:头尾是连接的(circle);所以呢就是考虑在头部切断!变成链状的情况就可以复用模块I啦;
- 第一个房子偷:helper(nums[:-1])
- 第一个房子不偷:helper(nums[1:])
- 但是要注意当nums的长度为1时,nums[:-1]和nums[1:]都是[],所以单独加了一条边界处理;neetcode这里是直接把nums[0]加到最后的return中,妙哇!
def rob(nums: List[int]) -> int:
if len(nums) == 1: return nums[0]
return max(helper(nums[:-1]), helper(nums[1:]))
def rob(nums: List[int]) -> int:
return max(nums[0], helper(nums[:-1]), helper(nums[1:]))
def helper(nums: List[int]) -> int:
rob1, rob2 = 0, 0
for num in nums:
tmp = max(num + rob1, rob2)
rob1 = rob2
rob2 = tmp
return rob2
5. Longest Palindromic Substring
- 参考neetcode+评论区改进!后来发现是英版lc中的most votes的第二个!
- 主要思路:对s中的元素s[index],逐渐左右散开,判断是否是回文;【妙蛙种子的日常简直就是!之前想到回文串只会从外向里check,没想到还可以从里到外哇!】
- 学习的点:
- 注意v1中slice的时间复杂度要考虑进去!(评论区的朋友赞一个)
- 可以看到v1中其实还有可复用的模块;v2做了改进!
- 奇偶情况的处理赞一个!【要不是看到这个解法,我可能又从mod出发讨论奇偶了衰orz】
def longestPalindrome(s: str) -> str:
res = ''
for i in range(len(s)):
# odd case: 'aba'
l, r = i, i
while l >= 0 and r < len(s) and s[l] == s[r]:
if r - l + 1 > len(res):
res = s[l: r + 1]
r += 1
l -= 1
# even case: 'abb'
l, r = i, i + 1
while l >= 0 and r < len(s) and s[l] == s[r]:
if r - l + 1 > len(res):
res = s[l: r + 1]
r += 1
l -= 1
return res
def longestPalindrome2(s: str) -> str:
res = ''
for i in range(len(s)):
# odd case: 'aba'
tmp1 = helper(s, i, i)
if len(tmp1) > len(res):
res = tmp1
# even case: 'abb'
tmp2 = helper(s, i, i + 1)
if len(tmp2) > len(res):
res = tmp2
return res
def helper(s, i, j):
while i >=0 and j < len(s) and s[i] == s[j]:
i -= 1
j += 1
return s[i+1: j]
647. Palindromic Substrings
- 站在巨人的肩膀上!【思路同#5,故略】
def countSubstrings(s):
count = 0
for i in range(len(s)):
count = helper(s, i, i, count)
count = helper(s, i, i + 1, count)
return count
def helper(s, i, j, count):
while i >= 0 and j < len(s) and s[i] == s[j]:
count += 1
i -= 1
j += 1
return count
91. Decode Ways
果然对字符串的处理生得不行orz,硬给他int()了哈哈哈哈哈哈
- 主要思路:
- #70走楼梯的进阶版(好吧就是换了个壳撒)
- 当前index的decode ways只取决于index-1和index-2位置的decode ways【当然这是由题目的限制得到的,1~26,最少一位,最多两位】
- 考虑index-1: 相当于直接在index-1的decode ways的每个项 加上单个decode(当然要判断这个单个decode是不是合法的
helper1
) - 考虑index-2:相当于在index-2的decode ways的每个项 加上由两位index-1, index构成的两位数(当然这里也是要判断这个两位数是不是合法的
helper2
,check一下是不是10~26,这里就把示例3中的case就考虑到了!)
- 考虑index-1: 相当于直接在index-1的decode ways的每个项 加上单个decode(当然要判断这个单个decode是不是合法的
def numDecodings(s):
a, b = 0, 1
for i in range(len(s)):
tmp1 = tmp2 = 0
if helper1(s, i):
tmp1 = b
if helper2(s, i - 1, i):
tmp2 = a
tmp = tmp1 + tmp2
a = b
b = tmp
return b
def helper1(s, i):
if int(s[i]) != 0:
return True
return False
def helper2(s, i, j):
if int(s[i]) * 10 + int(s[j]) >= 10 and int(s[i]) * 10 + int(s[j]) < 27:
return True
return False
明天看一下别人的解法