2021-10-28 每日打卡:腾讯精选50题
写在前面
“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,遵循LeetBook 列表/腾讯的刷题顺序,所有代码已通过。每日3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。
11. 盛最多水的容器
- 双指针:难点不是写法,而是怎么想到。因为这样的题其实第一反应是动态规划,他们的共同点都是可以抽象出这样的表达式:
res = f(i, j)
,即跟下标有关的一个表达式。但双指针的意义是,指导性移动,将遍历性的工作->根据关系进行某些步骤的掠过。而关系往往有两种:1. 两指针之间的关系 2 指针和自身之间的关系。如果发现结果/某种关系对i和j的变化有指导性意义,则使用指针而不是动态规划!
class Solution:
def maxArea(self, height: List[int]) -> int:
l, r = 0, len(height) - 1
res = 0
while l < r:
area = min(height[l], height[r]) * (r - l)
res = max(res, area)
if height[l] <= height[r]:
# 这两行的意义是"剪枝",当前面的高于后面的(因为宽也一定更长),没必要进行计算
# while l<r and height[l]>height[l+1]:
# l += 1
l +=1
else:
# while l<r and height[r]>height[r-1]:
# r -= 1
r -=1
return res
43. 字符串相乘
- 一步一步简化算法:模拟乘法(数乘数,不被允许)->简化,数乘字符,进位相加->再简化,字符乘字符,最后处理相加【第一遍未做出】
方法二的图示:
方法三的图示:即所有进位先记录保留,最后一起加上
class Solution:
def multiply(self, num1: str, num2: str) -> str:
# 必须对0特殊处理,否则会出现“0000”这样的特殊结果
if num1=='0' or num2=='0': return '0'
# 乘积的长度为len1+len2-1或len1+len2
# 分别使用10**(len-1)和(10**len)-1进行最小值和最大值的估计即可
len1, len2 = len(num1), len(num2)
res = [0]*(len1+len2)
for n1 in range(len1-1, -1, -1):
for n2 in range(len2-1, -1, -1):
# 无论是n1,n2谁向前一位,res对应的都应该向前一位,所以是线性关系
res[n1+n2+1]+=int(num1[n1])*int(num2[n2])
for index in range(len1+len2-1, -1, -1):
# 只需要往上一位进即可,因为上一位还是“累计加和”的形式
res[index-1] +=res[index]//10
res[index] = res[index]%10
res[0]="" if res[0]==0 else res[0]
return ''.join(str(ch) for ch in res)
344. 反转字符串
- 双指针原地交换即可😄:
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
l, r = 0, len(s)-1
while l<r:
s[l],s[r] = s[r],s[l]
l+=1
r-=1