diff --git a/problems/0037.解数独.md b/problems/0037.解数独.md index 7bc07252..d5b450aa 100644 --- a/problems/0037.解数独.md +++ b/problems/0037.解数独.md @@ -293,85 +293,40 @@ class Solution: """ Do not return anything, modify board in-place instead. """ - def backtrack(board): - for i in range(len(board)): #遍历行 - for j in range(len(board[0])): #遍历列 - if board[i][j] != ".": continue - for k in range(1,10): #(i, j) 这个位置放k是否合适 - if isValid(i,j,k,board): - board[i][j] = str(k) #放置k - if backtrack(board): return True #如果找到合适一组立刻返回 - board[i][j] = "." #回溯,撤销k - return False #9个数都试完了,都不行,那么就返回false - return True #遍历完没有返回false,说明找到了合适棋盘位置了 - def isValid(row,col,val,board): - for i in range(9): #判断行里是否重复 - if board[row][i] == str(val): + self.backtracking(board) + + def backtracking(self, board: List[List[str]]) -> bool: + # 若有解,返回True;若无解,返回False + for i in range(len(board)): # 遍历行 + for j in range(len(board[0])): # 遍历列 + # 若空格内已有数字,跳过 + if board[i][j] != '.': continue + for k in range(1, 10): + if self.is_valid(i, j, k, board): + board[i][j] = str(k) + if self.backtracking(board): return True + board[i][j] = '.' + # 若数字1-9都不能成功填入空格,返回False无解 + return False + return True # 有解 + + def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool: + # 判断同一行是否冲突 + for i in range(9): + if board[row][i] == str(val): + return False + # 判断同一列是否冲突 + for j in range(9): + if board[j][col] == str(val): + return False + # 判断同一九宫格是否有冲突 + start_row = (row // 3) * 3 + start_col = (col // 3) * 3 + for i in range(start_row, start_row + 3): + for j in range(start_col, start_col + 3): + if board[i][j] == str(val): return False - for j in range(9): #判断列里是否重复 - if board[j][col] == str(val): - return False - startRow = (row // 3) * 3 - startcol = (col // 3) * 3 - for i in range(startRow,startRow + 3): #判断9方格里是否重复 - for j in range(startcol,startcol + 3): - if board[i][j] == str(val): - return False - return True - backtrack(board) -``` - -Python3: - -```python3 -class Solution: - def __init__(self) -> None: - self.board = [] - - def isValid(self, row: int, col: int, target: int) -> bool: - for idx in range(len(self.board)): - # 同列是否重复 - if self.board[idx][col] == str(target): - return False - # 同行是否重复 - if self.board[row][idx] == str(target): - return False - # 9宫格里是否重复 - box_row, box_col = (row // 3) * 3 + idx // 3, (col // 3) * 3 + idx % 3 - if self.board[box_row][box_col] == str(target): - return False return True - - def getPlace(self) -> List[int]: - for row in range(len(self.board)): - for col in range(len(self.board)): - if self.board[row][col] == ".": - return [row, col] - return [-1, -1] - - def isSolved(self) -> bool: - row, col = self.getPlace() # 找个空位置 - - if row == -1 and col == -1: # 没有空位置,棋盘被填满的 - return True - - for i in range(1, 10): - if self.isValid(row, col, i): # 检查这个空位置放i,是否合适 - self.board[row][col] = str(i) # 放i - if self.isSolved(): # 合适,立刻返回, 填下一个空位置。 - return True - self.board[row][col] = "." # 不合适,回溯 - - return False # 空位置没法解决 - - def solveSudoku(self, board: List[List[str]]) -> None: - """ - Do not return anything, modify board in-place instead. - """ - if board is None or len(board) == 0: - return - self.board = board - self.isSolved() ``` Go: diff --git a/problems/0337.打家劫舍III.md b/problems/0337.打家劫舍III.md index 949137c3..8456adf1 100644 --- a/problems/0337.打家劫舍III.md +++ b/problems/0337.打家劫舍III.md @@ -368,6 +368,41 @@ class Solution: return (val1, val2) ``` +Go: + +> 动态规划 + +```go +func rob(root *TreeNode) int { + res := robTree(root) + return max(res[0], res[1]) +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func robTree(cur *TreeNode) []int { + if cur == nil { + return []int{0, 0} + } + // 后序遍历 + left := robTree(cur.Left) + right := robTree(cur.Right) + + // 考虑去偷当前的屋子 + robCur := cur.Val + left[0] + right[0] + // 考虑不去偷当前的屋子 + notRobCur := max(left[0], left[1]) + max(right[0], right[1]) + + // 注意顺序:0:不偷,1:去偷 + return []int{notRobCur, robCur} +} +``` + JavaScript: > 动态规划 diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index 05c272c6..e5750ff7 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -226,6 +226,32 @@ class Solution: return taraget == dp[taraget] ``` Go: +```go +// 分割等和子集 动态规划 +// 时间复杂度O(n^2) 空间复杂度O(n) +func canPartition(nums []int) bool { + sum := 0 + for _, num := range nums { + sum += num + } + // 如果 nums 的总和为奇数则不可能平分成两个子集 + if sum % 2 == 1 { + return false + } + + target := sum / 2 + dp := make([]int, target + 1) + + for _, num := range nums { + for j := target; j >= num; j-- { + if dp[j] < dp[j - num] + num { + dp[j] = dp[j - num] + num + } + } + } + return dp[target] == target +} +``` ```go func canPartition(nums []int) bool { diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 29243c6d..60f7115d 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -200,17 +200,14 @@ func reverse(b []byte, left, right int){ JavaScript: ```javascript -var reverseLeftWords = function (s, n) { - const reverse = (str, left, right) => { - let strArr = str.split(""); - for (; left < right; left++, right--) { - [strArr[left], strArr[right]] = [strArr[right], strArr[left]]; - } - return strArr.join(""); - } - s = reverse(s, 0, n - 1); - s = reverse(s, n, s.length - 1); - return reverse(s, 0, s.length - 1); +var reverseLeftWords = function(s, n) { + const length = s.length; + let i = 0; + while (i < length - n) { + s = s[length - 1] + s; + i++; + } + return s.slice(0, length); }; ```