数组与字符串必刷 10 题
掌握这 10 题,数组与字符串面试基本无忧。
1. 两数之和(LeetCode 1)
def two_sum(nums, target):
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
考点:哈希表 O(n) 解法,暴力 O(n²) 会超时。
2. 三数之和(LeetCode 15)
def three_sum(nums):
nums.sort()
result = []
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, len(nums) - 1
while left < right:
s = nums[i] + nums[left] + nums[right]
if s < 0:
left += 1
elif s > 0:
right -= 1
else:
result.append([nums[i], nums[left], nums[right]])
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
left += 1
right -= 1
return result
考点:排序 + 双指针,注意去重。
3. 无重复字符的最长子串(LeetCode 3)
def length_of_longest_substring(s):
char_set = set()
left = 0
result = 0
for right in range(len(s)):
while s[right] in char_set:
char_set.remove(s[left])
left += 1
char_set.add(s[right])
result = max(result, right - left + 1)
return result
考点:滑动窗口 + 哈希集合。
4. 最小覆盖子串(LeetCode 76)
from collections import Counter
def min_window(s, t):
need = Counter(t)
window = {}
left = valid = 0
start, length = 0, float('inf')
for right in range(len(s)):
c = s[right]
if c in need:
window[c] = window.get(c, 0) + 1
if window[c] == need[c]:
valid += 1
while valid == len(need):
if right - left + 1 < length:
start, length = left, right - left + 1
d = s[left]
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1
left += 1
return "" if length == float('inf') else s[start:start + length]
考点:滑动窗口 + 哈希验证,Hard 题经典模板。
5. 盛最多水的容器(LeetCode 11)
def max_area(height):
left, right = 0, len(height) - 1
result = 0
while left < right:
area = min(height[left], height[right]) * (right - left)
result = max(result, area)
if height[left] < height[right]:
left += 1
else:
right -= 1
return result
考点:双指针 + 贪心,移动较短边才可能增大面积。
6. 移动零(LeetCode 283)
def move_zeroes(nums):
slow = 0
for fast in range(len(nums)):
if nums[fast] != 0:
nums[slow], nums[fast] = nums[fast], nums[slow]
slow += 1
考点:快慢指针原地修改。
7. 和为 K 的子数组(LeetCode 560)
from collections import defaultdict
def subarray_sum(nums, k):
prefix_count = defaultdict(int)
prefix_count[0] = 1
prefix = 0
count = 0
for num in nums:
prefix += num
count += prefix_count[prefix - k]
prefix_count[prefix] += 1
return count
考点:前缀和 + 哈希,O(n) 经典。
8. 旋转数组中的最小值(LeetCode 153)
def find_min(nums):
left, right = 0, len(nums) - 1
while left < right:
mid = left + (right - left) // 2
if nums[mid] > nums[right]:
left = mid + 1
else:
right = mid
return nums[left]
考点:旋转数组二分查找。
9. 合并区间(LeetCode 56)
def merge(intervals):
if not intervals:
return []
intervals.sort(key=lambda x: x[0])
result = [intervals[0]]
for i in range(1, len(intervals)):
if intervals[i][0] <= result[-1][1]:
result[-1][1] = max(result[-1][1], intervals[i][1])
else:
result.append(intervals[i])
return result
考点:排序 + 贪心合并。
10. 除自身以外数组的乘积(LeetCode 238)
def product_except_self(nums):
n = len(nums)
result = [1] * n
prefix = 1
for i in range(n):
result[i] = prefix
prefix *= nums[i]
suffix = 1
for i in range(n - 1, -1, -1):
result[i] *= suffix
suffix *= nums[i]
return result
考点:前缀积 + 后缀积,O(1) 额外空间。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。