title: LeetCode Hot 100 题解全系列
date: 2026-02-27 10:00:00
tags: [LeetCode, 算法, 面试, Hot100]
categories: Leetcode
description: 系统整理 LeetCode Hot 100 高频题目,从思路分析到多语言实现,助力算法面试备战
toc: true
comments: true
cover: https://你的图床链接/leetcode-hot100-cover.png # 可选,替换为你的封面图链接

🌟 本系列系统整理 LeetCode 官方 Hot 100 高频题目,从思路分析到多语言实现,帮助你高效备战算法面试。

目录

  1. 两数之和 (Two Sum) - 哈希表
  2. 两数相加 (Add Two Numbers) - 链表
  3. 无重复字符的最长子串 - 滑动窗口
  4. 寻找两个正序数组的中位数 - 二分查找
  5. 最长回文子串 - 中心扩展

1. 两数之和 (Two Sum)

题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

plaintext

1
2
3
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例 2:

plaintext

1
2
输入:nums = [3,2,4], target = 6
输出:[1,2]

提示:

  • 2 <= nums.length <= 10^4
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9
  • 只会存在一个有效答案

核心思路

解法 时间复杂度 空间复杂度 核心逻辑
暴力枚举 O(n²) O(1) 双重循环遍历,逐一检查两数之和是否等于目标值
哈希表优化 O(n) O(n) 空间换时间,用哈希表存储已遍历元素的「值 - 索引」,每次计算 target - 当前值 并检查哈希表

代码实现

Java 版(哈希表)

java

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int[] twoSum(int[] nums, int target) {
// 哈希表存储已遍历的数字和对应的索引
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
// 找到补数,直接返回结果
if (map.containsKey(complement)) {
return new int[] { map.get(complement), i };
}
// 未找到则将当前数字存入哈希表
map.put(nums[i], i);
}
// 题目保证有解,此处仅为语法完整性
throw new IllegalArgumentException("No two sum solution");
}
}

Python 版(哈希表)

python

运行

1
2
3
4
5
6
7
8
9
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashmap = {}
for index, num in enumerate(nums):
complement = target - num
if complement in hashmap:
return [hashmap[complement], index]
hashmap[num] = index
return []

常见坑点

  1. 误将「元素值」作为索引返回,而非题目要求的「数组下标」;
  2. 未处理数组中重复元素的情况(如 nums = [3,3]),但题目保证唯一解,无需额外处理;
  3. 暴力枚举法在数据量大时超时,面试中优先使用哈希表解法。

2. 两数相加 (Add Two Numbers)

题目描述

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

plaintext

1
2
3
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

plaintext

1
2
输入:l1 = [0], l2 = [0]
输出:[0]

核心思路

  1. 虚拟头节点:创建一个 dummy 节点简化链表操作,避免处理头节点为空的情况;
  2. 进位处理:遍历两个链表时,计算当前位的和 + 进位,新进位 = 总和 // 10,当前位值 = 总和 % 10;
  3. 边界处理:若其中一个链表遍历完毕,继续处理另一个链表的剩余节点;遍历结束后若进位 > 0,需新增节点存储进位。

代码实现

Java 版

java

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 链表节点定义
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0); // 虚拟头节点
ListNode curr = dummy;
int carry = 0; // 进位

while (l1 != null || l2 != null || carry != 0) {
// 取值,链表遍历完则取0
int x = (l1 != null) ? l1.val : 0;
int y = (l2 != null) ? l2.val : 0;

// 计算当前位总和与进位
int sum = x + y + carry;
carry = sum / 10;
curr.next = new ListNode(sum % 10);

// 移动指针
curr = curr.next;
if (l1 != null) l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
return dummy.next; // 跳过虚拟头节点
}
}

Python 版

python

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 链表节点定义
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next

class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(0)
curr = dummy
carry = 0

while l1 or l2 or carry:
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0

total = val1 + val2 + carry
carry = total // 10
curr.next = ListNode(total % 10)

curr = curr.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None

return dummy.next

常见坑点

  1. 忽略最后一位的进位(如 999 + 999 = 1998,需新增节点存储最高位的 1);
  2. 未处理两个链表长度不一致的情况;
  3. 直接修改原链表节点值,导致数据丢失(应新建节点存储结果)。

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

题目描述

给定一个字符串 s,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

plaintext

1
2
3
输入:s = "abcabcbb"
输出:3
解释:因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 2:

plaintext

1
2
3
输入:s = "bbbbb"
输出:1
解释:因为无重复字符的最长子串是 "b",所以其长度为 1

核心思路(滑动窗口)

  1. 窗口定义:用哈希集合存储当前窗口内的字符,左指针 left 表示窗口起始位置,右指针 right 遍历字符串;
  2. 窗口收缩:若当前字符已在集合中,不断右移左指针并移除对应字符,直到窗口内无重复;
  3. 更新结果:每次遍历更新最长子串长度。

代码实现

python

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
char_set = set()
left = 0
max_len = 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])
max_len = max(max_len, right - left + 1)

return max_len

总结

  1. 本文提供的是标准 Markdown 格式的 LeetCode Hot 100 题解,兼容 Obsidian/Hexo/ 所有编辑器;
  2. 每道题包含「题目描述 + 核心思路 + 多语言代码 + 坑点总结」,结构统一且信息完整;
  3. 代码块标注明确的语言类型,保证 Hexo 发布后语法高亮正常显示。
Author

Jiaru

Posted on

2026-02-27

Updated on

2026-02-27

Licensed under

Comments