2021-10-26 每日打卡:腾讯精选50题
写在前面
“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,遵循LeetBook 列表/腾讯的刷题顺序,所有代码已通过。每日3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。
8. 字符串转换整数 (atoi)
- 第二遍做啦,状态机
class Solution:
def myAtoi(self, s: str) -> int:
INT_MAX = 2**31-1
INT_MIN = -2**31
statedic = [
{"s":0, "c":1, "n":2},
{"s":3,"c":3,"n":2},
{"s":3,"c":3,"n":2},
]
state, next_state, res, signal = 0, "o", 0, 1
for ch in s:
if ch==" ":
next_state="s"
elif ch in "+-":
next_state = "c"
elif "0"<=ch<="9":
next_state = "n"
res *= 10
res += (ord(ch) - ord("0"))
# 注意这里对负数的处理:1. 负号一定要最后加 2. 拿正数比较时要反着来
res = min(INT_MAX, res) if signal==1 else min(-INT_MIN,res)
else: break
state = statedic[state][next_state]
# 在转移后接着判断,防止下一轮循环发生
# 状态转移了,才是真正的操作时候,否则“123-”这种,还未转移时就变更了signal
if state==3:
break
elif state == 1: signal =-1 if ch=="-" else 1
return signal*res
14. 最长公共前缀
- 比较简单,直接纵向比较即可:
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
length, count = len(strs[0]), len(strs)
for index in range(length):
c = strs[0][index]
if any(index == len(strs[num]) or strs[num][index] != c for num in range(1, count)):
return strs[0][:index]
return strs[0]
15. 三数之和
- 双指针碰撞(其实很像滑动窗口,根据当前结果大小而调整):
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
n = len(nums)
res = []
for first in range(n):
# 设置双指针都以右边,则第一个数大于0,代表找到所有的结果了
if nums[first]>0:
return res
# first>0防止[0, 0, 0],排序后和上一个比较,防止相同
if first>0 and nums[first]==nums[first-1]:
continue
L, R = first+1, n-1
while L<R:
if nums[first] + nums[L] + nums[R] == 0:
res.append([nums[first],nums[L],nums[R]])
# 如果找到合适的,但仍需要判断重复
while L<R and nums[L]==nums[L+1]: L += 1
while L<R and nums[R]==nums[R-1]: R -= 1
# 没有重复的而且找到一个值,继续找值
L,R = L+1,R-1
elif nums[first] + nums[L] + nums[R] > 0: R -= 1
else: L += 1
return res