Skip to main content

hot100

1. 两数之和

class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
d = {}
for i, num in enumerate(nums):
if target - num in d:
return [i, d[target- num]]
d[num] = i

49. 字母异位词分组

class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
d = {}
for str in strs:
str_ = "".join(sorted(str))
if str_ not in d:
d[str_] = [str]
else:
d[str_].append(str)
return list(d.values())

128. 最长连续序列✨

class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
s = set(nums)
max_len = 0
for i in s:
if i - 1 not in s: # 只需要从开头开始枚举
j = i
len_ = 0
while (j in s):
j += 1
len_ += 1
max_len = max(max_len, len_)
return max_len


283. 移动零

class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
ln = len(nums)
for i in range(ln):
if nums[i] == 0:
j = i
while j + 1 < ln and nums[j] == 0:
j += 1
print(i, j)
nums[i], nums[j] = nums[j], nums[i]

## 官方
def moveZeroes(self, nums: List[int]) -> None:
n = len(nums)
left = right = 0
while right < n:
if nums[right] != 0:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right += 1

11. 成水最多的容器

看题解:https://leetcode.cn/problems/container-with-most-water/solutions/94102/on-shuang-zhi-zhen-jie-fa-li-jie-zheng-que-xing-tu

class Solution:
def maxArea(self, h: List[int]) -> int:
l, r = 0, len(h) - 1
res = 0
while l < r:
area = min(h[l], h[r]) * (r - l)
res = max(res, area)
if h[l] <= h[r]:
l += 1
else:
r -= 1
return res

15.三数之和

推荐题解:https://leetcode.cn/problems/3sum/solutions/11525/3sumpai-xu-shuang-zhi-zhen-yi-dong-by-jyd

class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
res = []
ln = len(nums)
if ln < 3:
return res
for a in range(ln - 2):
if nums[a] > 0:
return res
if a > 0 and nums[a] == nums[a - 1]:
continue
b, c = a + 1, ln - 1
while b < c:
s = nums[a] + nums[b] + nums[c]
if s < 0:
b += 1
while b < c and nums[b] == nums[b - 1]: b += 1
elif s > 0:
c -= 1
while b < c and nums[c] == nums[c + 1]: c -= 1
else:
res.append([nums[a], nums[b], nums[c]])
b += 1
c -= 1
while b < c and nums[b] == nums[b - 1]: b += 1
while b < c and nums[c] == nums[c + 1]: c -= 1
return res

42. 接雨水

单调栈做法

class Solution:
def trap(self, h: List[int]) -> int:
res = 0
stack = []
for i in range(len(h)):
while stack and h[stack[-1]] < h[i]:
cur = stack.pop()
if not stack: #前面也没有高的柱子,不可能接到雨水
break
height = min(h[i], h[stack[-1]]) - h[cur] #当前能接到的雨水高度
res += (i - stack[-1] - 1) * height
stack.append(i)
return res

3. 无重复字符的最长子串

    def lengthOfLongestSubstring(self, s: str) -> int:
s_ = set()
res = 0
l, r = 0, 0
while r < len(s):
while r < len(s) and s[r] not in s_:
s_.add(s[r])
r += 1
res = max(res, r - l)
while l < r and r < len(s) and s[l] != s[r]:
s_.remove(s[l])
l += 1
l += 1
r += 1
return res

比较简略的c++写法:

    int lengthOfLongestSubstring(string s) {
int len = 0;
int n = s.size();
unordered_set<char> set;
for (int i = 0, j = 0; j < n; j++) {
while (set.count(s[j]))
set.erase(s[i++]);
set.insert(s[j]);
len = max(len, j - i + 1);
}
return len;
}

438. 找到字符串中所有字母异位词

固定滑动窗口

    def findAnagrams(self, s: str, p: str) -> List[int]:
slen , plen = len(s), len(p)
if slen < plen:
return []

ans = []
s_ = [0] * 26
p_ = [0] * 26
for i in range(plen):
s_[ord(s[i]) - 97] += 1
p_[ord(p[i]) - 97] += 1
if s_ == p_:
ans.append(0)
for i in range(slen - plen):
s_[ord(s[i]) - 97] -= 1
s_[ord(s[i + plen]) - 97] += 1
if s_ == p_:
ans.append(i + 1)
return ans

560. 和为 K 的子数组

前缀和 + hash(cnt保存当前以0为左边界所有前缀和出现的次数)

    def subarraySum(self, nums: List[int], k: int) -> int:
ans = s = 0
cnt = defaultdict(int)
for x in nums:
cnt[s] += 1
s += x
ans += cnt[s - k] ##之间为k
return ans

239. 滑动窗口最大值

简单做法:堆保存数据,右移时判断堆顶元素是否在窗口内

    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
n = len(nums)
q = [(-nums[i], i) for i in range(k)]
heapq.heapify(q)

ans = [-q[0][0]]
for i in range(k, n):
heapq.heappush(q, (-nums[i], i))
while (q[0][1] < i - k + 1):
heapq.heappop(q)
ans.append(-q[0][0])
return ans

优化:单调队列(不需要维护所有元素,只需要维护一个单调递减的队列元素,左侧的小元素相比于右侧大元素永远不可能成为答案)

class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
ans = [0] * (len(nums) - k + 1)
q = deque()

for i, x in enumerate(nums):
while q and nums[q[-1]] <= x:
q.pop()
q.append(i)
left = i - k + 1
if q[0] < left:
q.popleft()
if left >= 0:
ans[left] = nums[q[0]]
return ans