每天都做成详细的 step-by-step 计划。
---
## Day 1 — 字符串操作(60-90分钟)
### 第一步:看这些操作,每个自己手打一遍(20分钟)
```python
s = "Hello World"
# 基础操作
print(s[::-1]) # 反转 → "dlroW olleH"
print(s.upper()) # 全大写
print(s.lower()) # 全小写
print(s.strip()) # 去首尾空格
print(s.split(" ")) # 分割 → ["Hello", "World"]
print("-".join(["a","b","c"])) # 合并 → "a-b-c"
print(s.replace("l","x")) # 替换
print(s.count("l")) # 统计出现次数 → 3
print(s.find("World")) # 找位置 → 6
print(s.startswith("He")) # True
print(s.isdigit()) # 是否全是数字
print(s.isalpha()) # 是否全是字母
```
### 第二步:把这 3 个模板理解并默写(15分钟)
```python
# 模板1:判断回文
def is_palindrome(s):
s = s.lower().replace(" ", "") # 忽略大小写和空格
return s == s[::-1]
# 模板2:统计每个字符频率
from collections import Counter
def char_frequency(s):
return Counter(s)
# 模板3:反转句子里的单词顺序
def reverse_words(s):
return " ".join(s.split()[::-1])
# 测试
print(is_palindrome("A man a plan a canal Panama")) # True
print(char_frequency("hello")) # Counter({'l':2,'h':1,'e':1,'o':1})
print(reverse_words("hello world foo")) # "foo world hello"
```
### 第三步:去 HackerRack 做这 3 道题(30-45分钟)
1. **Reverse a String** — 搜索直接做
2. **String Validators** — 考 isdigit/isalpha/isupper
3. **Capitalize** — 考 split + join + capitalize()
> HackerRank 注册后 → 选 Python → Practice → Strings
### 今天结束前问自己:
- [ ] `s[::-1]` 和 `s.split()` 不看笔记能写出来吗?
- [ ] 3 道题都通过了吗?
- [ ] 有没有遇到边界条件出错(空字符串)?
---
## Day 2 — 列表 & 推导式(60-90分钟)
### 第一步:手打这些操作(20分钟)
```python
lst = [3, 1, 4, 1, 5, 9, 2, 6, 5]
print(sorted(lst)) # 升序(不改原列表)
print(sorted(lst, reverse=True)) # 降序
print(max(lst), min(lst)) # 最大最小
print(sum(lst)) # 求和
print(lst.count(5)) # 5 出现几次 → 2
print(list(set(lst))) # 去重(顺序不保证)
# enumerate 和 zip(很常用)
for i, val in enumerate(lst):
print(f"index {i}: {val}")
for a, b in zip([1,2,3], ["x","y","z"]):
print(a, b)
```
### 第二步:列表推导式重点练(15分钟)
```python
# 基础
squares = [x**2 for x in range(10)]
# 带条件过滤
evens = [x for x in range(20) if x % 2 == 0]
# 嵌套(二维矩阵)
matrix = [[i*j for j in range(1,4)] for i in range(1,4)]
# 字符串 + 列表组合
words = ["hello", "world", "python"]
upper_words = [w.upper() for w in words if len(w) > 4]
print(squares)
print(evens)
print(matrix)
print(upper_words)
```
### 第三步:把这个模板理解并默写(15分钟)
```python
# 两数之和(最经典的 Easy 题)
def two_sum(nums, target):
seen = {}
for i, n in enumerate(nums):
complement = target - n
if complement in seen:
return [seen[complement], i]
seen[n] = i
return []
print(two_sum([2,7,11,15], 9)) # [0, 1]
print(two_sum([3,2,4], 6)) # [1, 2]
print(two_sum([], 5)) # [] ← 边界条件
```
### 第三步:HackerRank 做这 3 道题
1. **List Comprehensions**
2. **Find the Runner-Up Score**
3. **Nested Lists**
---
## Day 3 — 字典 & 集合(60-90分钟)
### 第一步:手打操作(15分钟)
```python
d = {"name": "Alice", "age": 25}
# 安全取值(不会 KeyError)
print(d.get("name")) # Alice
print(d.get("salary", 0)) # 0(默认值)
# 遍历
for k, v in d.items():
print(k, v)
# 集合运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b) # 交集 {3, 4}
print(a | b) # 并集 {1,2,3,4,5,6}
print(a - b) # 差集 {1, 2}
```
### 第二步:defaultdict 专项练习(15分钟)
```python
from collections import defaultdict
# 场景1:统计词频(比普通 dict 方便很多)
def word_count(sentence):
freq = defaultdict(int)
for word in sentence.split():
freq[word] += 1
return dict(freq)
# 场景2:按某个属性分组
def group_by_length(words):
groups = defaultdict(list)
for w in words:
groups[len(w)].append(w)
return dict(groups)
print(word_count("the cat sat on the mat the cat"))
# {'the': 3, 'cat': 2, 'sat': 1, 'on': 1, 'mat': 1}
print(group_by_length(["hi","hello","hey","world","ok"]))
# {2: ['hi', 'ok'], 5: ['hello', 'world'], 3: ['hey']}
```
### 第三步:Counter 专项(10分钟)
```python
from collections import Counter
# 最常用的操作
c = Counter("abracadabra")
print(c) # 每个字符的频率
print(c.most_common(3)) # 前3个最常见的
print(c["a"]) # a 出现几次
print(list(c.keys())) # 所有出现的字符
# 找出现次数最多的字符,并列时取字母最小的
def most_frequent_char(s):
c = Counter(s)
max_count = max(c.values())
candidates = [ch for ch, cnt in c.items() if cnt == max_count]
return min(candidates) # 字母最小的
print(most_frequent_char("aabbcc")) # a
```
### 第四步:HackerRank 做这 3 道
1. **Collections.Counter()**
2. **DefaultDict Tutorial**
3. **Word Order**
---
## Day 4 — 数学逻辑(60分钟)
### 第一步:把这 5 个模板全部默写出来(30分钟)
不要看笔记,直接默写,写不出来再看:
```python
import math
# 1. FizzBuzz
def fizzbuzz(n):
for i in range(1, n+1):
if i % 15 == 0: print("FizzBuzz")
elif i % 3 == 0: print("Fizz")
elif i % 5 == 0: print("Buzz")
else: print(i)
# 2. 判断质数
def is_prime(n):
if n < 2: return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0: return False
return True
# 3. 斐波那契(返回第 n 个)
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
# 4. 最大公约数 & 最小公倍数
def gcd(a, b): return math.gcd(a, b)
def lcm(a, b): return a * b // math.gcd(a, b)
# 5. 数字各位求和
def digit_sum(n):
return sum(int(d) for d in str(abs(n)))
# 测试
fizzbuzz(15)
print([n for n in range(20) if is_prime(n)])
print([fibonacci(i) for i in range(10)])
print(gcd(48, 18), lcm(4, 6))
print(digit_sum(12345))
```
### 第二步:HackerRank 做
1. **Integers Come In All Sizes**
2. **Triangle Quest**
3. 任意一道 Math Easy 题
---
## Day 5 — 排序进阶(60分钟)
### 第一步:lambda 排序练习(20分钟)
```python
# 场景1:按元组第二个元素排序
students = [("Alice",85), ("Bob",92), ("Charlie",78), ("Dave",85)]
print(sorted(students, key=lambda x: x[1])) # 按分数升序
print(sorted(students, key=lambda x: x[1], reverse=True)) # 降序
# 场景2:按多个条件排序(先按分数降序,分数相同按名字升序)
print(sorted(students, key=lambda x: (-x[1], x[0])))
# 场景3:按字符串长度排序,长度相同按字母顺序
words = ["banana","apple","kiwi","fig","cherry"]
print(sorted(words, key=lambda x: (len(x), x)))
# 场景4:对字典列表排序
people = [{"name":"Alice","age":30}, {"name":"Bob","age":25}]
print(sorted(people, key=lambda x: x["age"]))
```
### 第二步:双指针模板(20分钟)
```python
# 模板1:判断回文
def is_palindrome(lst):
left, right = 0, len(lst) - 1
while left < right:
if lst[left] != lst[right]: return False
left += 1
right -= 1
return True
# 模板2:找数组中两个数之和等于 target(数组已排序)
def two_sum_sorted(nums, target):
left, right = 0, len(nums) - 1
while left < right:
s = nums[left] + nums[right]
if s == target: return [left, right]
elif s < target: left += 1
else: right -= 1
return []
print(is_palindrome([1,2,3,2,1])) # True
print(two_sum_sorted([1,3,5,7,9], 8)) # [0, 3]
```
### 第三步:自己写一道题
> 给一个字符串列表,先按字符串长度排序,长度相同的按字母倒序排。写完测试边界:空列表、只有一个元素。
---
## Day 6 — 栈 & 队列(60分钟)
### 第一步:基础操作(10分钟)
```python
from collections import deque
# 栈(LIFO)
stack = []
stack.append("a")
stack.append("b")
print(stack.pop()) # b
print(stack[-1]) # 查看栈顶不弹出
# 队列(FIFO)
queue = deque()
queue.append(1)
queue.append(2)
print(queue.popleft()) # 1(从左边出)
```
### 第二步:括号匹配(最经典栈题,必须会)(20分钟)
```python
def is_valid(s):
stack = []
mapping = {")": "(", "}": "{", "]": "["}
for char in s:
if char in mapping:
top = stack.pop() if stack else "#"
if mapping[char] != top:
return False
else:
stack.append(char)
return not stack
# 测试(包括边界条件)
print(is_valid("()[]{}")) # True
print(is_valid("([)]")) # False
print(is_valid("{[]}")) # True
print(is_valid("")) # True(空字符串)
print(is_valid("]")) # False(只有右括号)
```
### 第三步:用栈解一道实际题(20分钟)
```python
# 题目:给一个整数数组,用栈找出每个元素右边第一个比它大的数
# 输入: [2, 1, 2, 4, 3]
# 输出: [4, 2, 4, -1, -1](没有则返回 -1)
def next_greater(nums):
result = [-1] * len(nums)
stack = [] # 存 index
for i, n in enumerate(nums):
while stack and nums[stack[-1]] < n:
idx = stack.pop()
result[idx] = n
stack.append(i)
return result
print(next_greater([2, 1, 2, 4, 3])) # [4, 2, 4, -1, -1]
```
---
## Day 7 — 复盘日(45分钟)
### Step 1:做一张自己的错题表(15分钟)
回顾这一周,记录:
- 哪类题最容易出错?
- 哪个语法经常忘?
- 边界条件有没有经常漏掉?
### Step 2:不看笔记,默写这些模板(20分钟)
```
1. 判断回文
2. 统计字符频率(Counter)
3. 两数之和(用 dict)
4. 判断质数
5. 括号匹配(用栈)
```
### Step 3:限时做 2 道综合题(30分钟,每题15分钟)
题目1:
> 给一个字符串,找出第一个不重复的字符,返回它的 index。如果不存在返回 -1。
> 例:"leetcode" → 0,"aabb" → -1
题目2:
> 给一个整数数组,返回乘积最大的三个数之积。
> 例:[1,2,3,4] → 24,[-10,-10,1,3,2] → 300
---
## Day 8 — 二维数组(60分钟)
### 第一步:基础操作(15分钟)
```python
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
rows = len(matrix)
cols = len(matrix[0])
# 遍历
for i in range(rows):
for j in range(cols):
print(matrix[i][j], end=" ")
print()
# 转置
transposed = list(map(list, zip(*matrix)))
# [[1,4,7],[2,5,8],[3,6,9]]
# 对角线元素
main_diag = [matrix[i][i] for i in range(rows)] # [1,5,9]
anti_diag = [matrix[i][rows-1-i] for i in range(rows)] # [3,5,7]
```
### 第二步:常见考题(30分钟)
```python
# 1. 顺时针旋转 90 度
def rotate_90(matrix):
return [list(row) for row in zip(*matrix[::-1])]
# 2. 螺旋遍历(偶尔出)
def spiral_order(matrix):
result = []
while matrix:
result += matrix.pop(0)
matrix = list(zip(*matrix))[::-1]
return result
print(rotate_90([[1,2,3],[4,5,6],[7,8,9]]))
print(spiral_order([[1,2,3],[4,5,6],[7,8,9]]))
```
---
## Day 9 — 递归(60分钟)
### 第一步:理解递归三要素(10分钟)
```
1. 终止条件(base case)
2. 递归调用(缩小问题规模)
3. 返回值
```
### 第二步:练习这 3 个(30分钟)
```python
# 1. 二分搜索
def binary_search(arr, target, left=0, right=None):
if right is None: right = len(arr) - 1
if left > right: return -1
mid = (left + right) // 2
if arr[mid] == target: return mid
elif arr[mid] < target: return binary_search(arr, target, mid+1, right)
else: return binary_search(arr, target, left, mid-1)
# 2. 幂运算
def power(base, exp):
if exp == 0: return 1
if exp % 2 == 0:
half = power(base, exp // 2)
return half * half
return base * power(base, exp - 1)
# 3. 展平嵌套列表
def flatten(lst):
result = []
for item in lst:
if isinstance(item, list):
result.extend(flatten(item))
else:
result.append(item)
return result
print(binary_search([1,3,5,7,9,11], 7)) # 3
print(power(2, 10)) # 1024
print(flatten([1,[2,[3,4]],5])) # [1,2,3,4,5]
```
---
## Day 10 — 补弱点日
### 根据你第 7 天的错题表,选对应的练习:
**如果字符串是弱点:**
- 做 HackerRank → Strings 里 5 道你没做过的题
**如果排序/lambda 是弱点:**
```python
# 专练这类题
data = [("Alice",85,"F"), ("Bob",92,"M"), ("Charlie",85,"M")]
# 按分数降序,分数相同按名字升序排
sorted(data, key=lambda x: (-x[1], x[0]))
```
**如果边界条件是弱点:**
- 把 Day 1-6 所有模板加上这些测试用例重跑一遍:
```python
# 空输入
func([])
func("")
# 单个元素
func([1])
func("a")
# 负数
func([-1, -2, -3])
# 全相同
func([5,5,5,5])
```
---
## Day 11 — 限时模拟①(60分钟)
### 规则
- 3 道题,每题严格 **15 分钟**,计时器一定要开
- 时间到了立刻停,不管写没写完
- 剩余 15 分钟复盘
### 今日题目(自己去 HackerRank 找同类型):
**题1(字符串):** 给一个字符串,判断它是否是另一个字符串的字母异位词(anagram)
```
"listen" 和 "silent" → True
"hello" 和 "world" → False
```
**题2(数组):** 给一个数组,找出所有出现次数超过 n//2 的元素
```
[3,2,3] → [3]
[1,1,1,2,2,3] → [1]
```
**题3(数学):** 给一个数,判断它是不是完全平方数,不能用 sqrt
```
16 → True
14 → False
```
### 15分钟复盘:
- 哪道题超时了?为什么?
- 有没有边界条件没考虑到?
---
## Day 12 — 限时模拟②(60分钟)
### 完全模拟 SHL 节奏:2 道题,45 分钟
**题1:**
> 给一个字符串,找出出现次数最多的字符。如果有多个字符次数相同,返回字母表中最小的那个。空字符串返回空字符串。
```python
# 期望输出
most_frequent("aabbbcc") → "b"
most_frequent("aabb") → "a"
most_frequent("") → ""
```
**题2:**
> 给一个整数数组和目标值 target,找出数组中所有和等于 target 的不重复二元组,返回列表。
```python
# 期望输出
find_pairs([1,2,3,4,5,6], 7) → [(1,6),(2,5),(3,4)]
find_pairs([1,1,2,3], 4) → [(1,3)] # 不重复
find_pairs([], 5) → []
```
**做完之后对答案:** 所有测试用例过了吗?
---
## Day 13 — 边界条件专项(45分钟)
### 把这 6 类边界条件变成习惯
每道题写完之前都问自己这 6 个问题:
```python
"""
1. 输入为空? → [] 或 "" 或 None
2. 只有一个元素? → 不要假设 len >= 2
3. 有负数? → 数学逻辑还成立吗
4. 有重复元素? → 去重逻辑对吗
5. 返回类型对吗? → 要 list 别返回 tuple,要 int 别返回 float
6. 数字超大? → Python 不会溢出,但逻辑还对吗
"""
# 练习:给下面这个函数加边界条件处理
def find_max_pair_sum(nums):
# 找两个数之和的最大值
nums.sort()
return nums[-1] + nums[-2]
# 问题:如果 nums 是空列表?如果只有一个元素?
# 修复版:
def find_max_pair_sum_safe(nums):
if len(nums) < 2: return None # 或者 raise ValueError
nums.sort()
return nums[-1] + nums[-2]
```
### 专项练习:把 Day 11-12 的题全部加上边界测试重跑一遍
---
## Day 14 — 考前最终模拟(75分钟)
### 模拟考试(60分钟)
找安静的地方,手机放一边,**不查任何资料**:
**题1:** 给一个句子,返回其中最长的单词。如果有多个同样长的,返回第一个出现的。
**题2:** 给一个正整数,判断它是否是回文数(不转成字符串来做)。
**题3:** 给两个列表 A 和 B,找出所有在 A 中出现但不在 B 中的元素,以及在 B 中出现但不在 A 中的元素,合并返回(去重,升序)。
### 最后15分钟:检查清单
```
✅ 每道题的边界条件都处理了吗?
✅ 函数有 return 吗(别忘了返回值)?
✅ 测试用例都跑过了吗?
✅ 变量名是否清晰(别用 a/b/x 这种)?
```
### 考试当天记住
- 先**读完所有题目**,从最有把握的开始
- 能通过部分测试用例也比完全不提交好
- 代码**能跑通**比最优解更重要
- 时间不够时,优先保证已写部分是对的
---
想要我帮你出每天的参考答案,或者模拟出题吗?