Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c3cc5fb

Browse files
Update
2 parents 104ba7c + bed1f5a commit c3cc5fb

File tree

61 files changed

+1995
-612
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1995
-612
lines changed

‎problems/0017.电话号码的字母组合.md‎

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -282,61 +282,74 @@ class Solution {
282282
```
283283

284284
## Python
285-
286-
```Python
285+
**回溯**
286+
```python3
287287
class Solution:
288-
ans = []
289-
s = ''
290-
letterMap = {
291-
'2': 'abc',
292-
'3': 'def',
293-
'4': 'ghi',
294-
'5': 'jkl',
295-
'6': 'mno',
296-
'7': 'pqrs',
297-
'8': 'tuv',
298-
'9': 'wxyz'
299-
}
288+
def __init__(self):
289+
self.answers: List[str] = []
290+
self.answer: str = ''
291+
self.letter_map = {
292+
'2': 'abc',
293+
'3': 'def',
294+
'4': 'ghi',
295+
'5': 'jkl',
296+
'6': 'mno',
297+
'7': 'pqrs',
298+
'8': 'tuv',
299+
'9': 'wxyz'
300+
}
300301

301-
def letterCombinations(self, digits):
302-
self.ans.clear()
303-
if digits == '':
304-
return self.ans
302+
def letterCombinations(self, digits: str) -> List[str]:
303+
self.answers.clear()
304+
if not digits: return []
305305
self.backtracking(digits, 0)
306-
return self.ans
307-
308-
def backtracking(self, digits, index):
309-
if index == len(digits):
310-
self.ans.append(self.s)
311-
return
312-
else:
313-
letters = self.letterMap[digits[index]] # 取出数字对应的字符集
314-
for letter in letters:
315-
self.s = self.s + letter # 处理
316-
self.backtracking(digits, index + 1)
317-
self.s = self.s[:-1] # 回溯
306+
return self.answers
307+
308+
def backtracking(self, digits: str, index: int) -> None:
309+
# 回溯函数没有返回值
310+
# Base Case
311+
if index == len(digits): # 当遍历穷尽后的下一层时
312+
self.answers.append(self.answer)
313+
return
314+
# 单层递归逻辑
315+
letters: str = self.letter_map[digits[index]]
316+
for letter in letters:
317+
self.answer += letter # 处理
318+
self.backtracking(digits, index + 1) # 递归至下一层
319+
self.answer = self.answer[:-1] # 回溯
318320
```
319-
320-
python3:
321-
322-
```py
321+
**回溯简化**
322+
```python3
323323
class Solution:
324+
def __init__(self):
325+
self.answers: List[str] = []
326+
self.letter_map = {
327+
'2': 'abc',
328+
'3': 'def',
329+
'4': 'ghi',
330+
'5': 'jkl',
331+
'6': 'mno',
332+
'7': 'pqrs',
333+
'8': 'tuv',
334+
'9': 'wxyz'
335+
}
336+
324337
def letterCombinations(self, digits: str) -> List[str]:
325-
res = []
326-
s =""
327-
letterMap = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
328-
ifnotlen(digits): return res
329-
defbacktrack(digits,index, s):
330-
if index ==len(digits):
331-
return res.append(s)
332-
digit =int(digits[index]) #将index指向的数字转为int
333-
letters = letterMap[digit] #取数字对应的字符集
334-
for i inrange(len(letters)):
335-
s += letters[i]
336-
backtrack(digits, index+1, s) #递归,注意index+1,一下层要处理下一个数字
337-
s = s[:-1] #回溯
338-
backtrack(digits, 0, s)
339-
return res
338+
self.answers.clear()
339+
ifnot digits: return []
340+
self.backtracking(digits, 0, '')
341+
return self.answers
342+
343+
defbacktracking(self, digits: str, index: int, answer: str) -> None:
344+
# 回溯函数没有返回值
345+
# Base Case
346+
if index ==len(digits): # 当遍历穷尽后的下一层时
347+
self.answers.append(answer)
348+
return
349+
# 单层递归逻辑
350+
letters: str=self.letter_map[digits[index]]
351+
for letter in letters:
352+
self.backtracking(digits, index +1, answer + letter) # 递归至下一层 + 回溯
340353
```
341354

342355

‎problems/0019.删除链表的倒数第N个节点.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
* fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作),如图:
5151
<img src='https://code-thinking.cdn.bcebos.com/pics/19.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B91.png' width=600> </img></div>
5252

53-
* fast和slow同时移动,之道fast指向末尾,如题:
53+
* fast和slow同时移动,直到fast指向末尾,如题:
5454
<img src='https://code-thinking.cdn.bcebos.com/pics/19.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B92.png' width=600> </img></div>
5555

5656
* 删除slow指向的下一个节点,如图:

‎problems/0028.实现strStr.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
215215

216216
其实**这并不涉及到KMP的原理,而是具体实现,next数组即可以就是前缀表,也可以是前缀表统一减一(右移一位,初始位置为-1)。**
217217

218-
后面我会提供两种不同的实现代码,大家就明白了了
218+
后面我会提供两种不同的实现代码,大家就明白了
219219

220220
# 使用next数组来匹配
221221

‎problems/0035.搜索插入位置.md‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,24 @@ class Solution {
227227
}
228228
}
229229
```
230-
230+
Golang:
231+
```golang
232+
// 第一种二分法
233+
func searchInsert(nums []int, target int) int {
234+
l, r := 0, len(nums) - 1
235+
for l <= r{
236+
m := l + (r - l)/2
237+
if nums[m] == target{
238+
return m
239+
}else if nums[m] > target{
240+
r = m - 1
241+
}else{
242+
l = m + 1
243+
}
244+
}
245+
return r + 1
246+
}
247+
```
231248

232249
### Python
233250
```python3

‎problems/0037.解数独.md‎

Lines changed: 30 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -292,85 +292,40 @@ class Solution:
292292
"""
293293
Do not return anything, modify board in-place instead.
294294
"""
295-
def backtrack(board):
296-
for i in range(len(board)): #遍历行
297-
for j in range(len(board[0])): #遍历列
298-
if board[i][j] != ".": continue
299-
for k in range(1,10): #(i, j) 这个位置放k是否合适
300-
if isValid(i,j,k,board):
301-
board[i][j] = str(k) #放置k
302-
if backtrack(board): return True #如果找到合适一组立刻返回
303-
board[i][j] = "." #回溯,撤销k
304-
return False #9个数都试完了,都不行,那么就返回false
305-
return True #遍历完没有返回false,说明找到了合适棋盘位置了
306-
def isValid(row,col,val,board):
307-
for i in range(9): #判断行里是否重复
308-
if board[row][i] == str(val):
309-
return False
310-
for j in range(9): #判断列里是否重复
311-
if board[j][col] == str(val):
312-
return False
313-
startRow = (row // 3) * 3
314-
startcol = (col // 3) * 3
315-
for i in range(startRow,startRow + 3): #判断9方格里是否重复
316-
for j in range(startcol,startcol + 3):
317-
if board[i][j] == str(val):
318-
return False
319-
return True
320-
backtrack(board)
321-
```
322-
323-
### Python3
324-
325-
```python3
326-
class Solution:
327-
def __init__(self) -> None:
328-
self.board = []
329-
330-
def isValid(self, row: int, col: int, target: int) -> bool:
331-
for idx in range(len(self.board)):
332-
# 同列是否重复
333-
if self.board[idx][col] == str(target):
295+
self.backtracking(board)
296+
297+
def backtracking(self, board: List[List[str]]) -> bool:
298+
# 若有解,返回True;若无解,返回False
299+
for i in range(len(board)): # 遍历行
300+
for j in range(len(board[0])): # 遍历列
301+
# 若空格内已有数字,跳过
302+
if board[i][j] != '.': continue
303+
for k in range(1, 10):
304+
if self.is_valid(i, j, k, board):
305+
board[i][j] = str(k)
306+
if self.backtracking(board): return True
307+
board[i][j] = '.'
308+
# 若数字1-9都不能成功填入空格,返回False无解
334309
return False
335-
# 同行是否重复
336-
if self.board[row][idx] == str(target):
310+
return True # 有解
311+
312+
def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:
313+
# 判断同一行是否冲突
314+
for i in range(9):
315+
if board[row][i] == str(val):
337316
return False
338-
# 9宫格里是否重复
339-
box_row, box_col = (row //3) *3+ idx //3, (col //3) *3+ idx %3
340-
if self.board[box_row][box_col] == str(target):
317+
# 判断同一列是否冲突
318+
for j inrange(9):
319+
if board[j][col] == str(val):
341320
return False
321+
# 判断同一九宫格是否有冲突
322+
start_row = (row // 3) * 3
323+
start_col = (col // 3) * 3
324+
for i in range(start_row, start_row + 3):
325+
for j in range(start_col, start_col + 3):
326+
if board[i][j] == str(val):
327+
return False
342328
return True
343-
344-
def getPlace(self) -> List[int]:
345-
for row in range(len(self.board)):
346-
for col in range(len(self.board)):
347-
if self.board[row][col] == ".":
348-
return [row, col]
349-
return [-1, -1]
350-
351-
def isSolved(self) -> bool:
352-
row, col = self.getPlace() # 找个空位置
353-
354-
if row == -1 and col == -1: # 没有空位置,棋盘被填满的
355-
return True
356-
357-
for i in range(1, 10):
358-
if self.isValid(row, col, i): # 检查这个空位置放i,是否合适
359-
self.board[row][col] = str(i) # 放i
360-
if self.isSolved(): # 合适,立刻返回, 填下一个空位置。
361-
return True
362-
self.board[row][col] = "." # 不合适,回溯
363-
364-
return False # 空位置没法解决
365-
366-
def solveSudoku(self, board: List[List[str]]) -> None:
367-
"""
368-
Do not return anything, modify board in-place instead.
369-
"""
370-
if board is None or len(board) == 0:
371-
return
372-
self.board = board
373-
self.isSolved()
374329
```
375330

376331
### Go

‎problems/0039.组合总和.md‎

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -264,25 +264,73 @@ class Solution {
264264
}
265265
```
266266

267-
## Python
267+
## Python
268+
**回溯**
268269
```python3
269270
class Solution:
271+
def __init__(self):
272+
self.path = []
273+
self.paths = []
274+
275+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
276+
'''
277+
因为本题没有组合数量限制,所以只要元素总和大于target就算结束
278+
'''
279+
self.path.clear()
280+
self.paths.clear()
281+
self.backtracking(candidates, target, 0, 0)
282+
return self.paths
283+
284+
def backtracking(self, candidates: List[int], target: int, sum_: int, start_index: int) -> None:
285+
# Base Case
286+
if sum_ == target:
287+
self.paths.append(self.path[:]) # 因为是shallow copy,所以不能直接传入self.path
288+
return
289+
if sum_ > target:
290+
return
291+
292+
# 单层递归逻辑
293+
for i in range(start_index, len(candidates)):
294+
sum_ += candidates[i]
295+
self.path.append(candidates[i])
296+
self.backtracking(candidates, target, sum_, i) # 因为无限制重复选取,所以不是i-1
297+
sum_ -= candidates[i] # 回溯
298+
self.path.pop() # 回溯
299+
```
300+
**剪枝回溯**
301+
```python3
302+
class Solution:
303+
def __init__(self):
304+
self.path = []
305+
self.paths = []
306+
270307
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
271-
res = []
272-
path = []
273-
def backtrack(candidates,target,sum,startIndex):
274-
if sum > target: return
275-
if sum == target: return res.append(path[:])
276-
for i in range(startIndex,len(candidates)):
277-
if sum + candidates[i] >target: return #如果 sum + candidates[i] > target 就终止遍历
278-
sum += candidates[i]
279-
path.append(candidates[i])
280-
backtrack(candidates,target,sum,i) #startIndex = i:表示可以重复读取当前的数
281-
sum -= candidates[i] #回溯
282-
path.pop() #回溯
283-
candidates = sorted(candidates) #需要排序
284-
backtrack(candidates,target,0,0)
285-
return res
308+
'''
309+
因为本题没有组合数量限制,所以只要元素总和大于target就算结束
310+
'''
311+
self.path.clear()
312+
self.paths.clear()
313+
314+
# 为了剪枝需要提前进行排序
315+
candidates.sort()
316+
self.backtracking(candidates, target, 0, 0)
317+
return self.paths
318+
319+
def backtracking(self, candidates: List[int], target: int, sum_: int, start_index: int) -> None:
320+
# Base Case
321+
if sum_ == target:
322+
self.paths.append(self.path[:]) # 因为是shallow copy,所以不能直接传入self.path
323+
return
324+
# 单层递归逻辑
325+
# 如果本层 sum + condidates[i] > target,就提前结束遍历,剪枝
326+
for i in range(start_index, len(candidates)):
327+
if sum_ + candidates[i] > target:
328+
return
329+
sum_ += candidates[i]
330+
self.path.append(candidates[i])
331+
self.backtracking(candidates, target, sum_, i) # 因为无限制重复选取,所以不是i-1
332+
sum_ -= candidates[i] # 回溯
333+
self.path.pop() # 回溯
286334
```
287335

288336
## Go

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /