Retranslate the complete English edition from Simplified Chinese (#2010)

* Retranslate the complete English edition from Simplified Chinese

* Polish three English explanations after reader-focused review
This commit is contained in:
Yudong Jin
2026-10-31 03:35:51 +08:00
committed by GitHub
parent ef46e2ed95
commit 14c314c08c
1502 changed files with 29459 additions and 23517 deletions

View File

@@ -14,48 +14,48 @@ def backtrack(
diags1: list[bool],
diags2: list[bool],
):
"""Backtracking algorithm: N queens"""
# When all rows are placed, record the solution
"""Backtracking: n-queens"""
# Record a solution when a queen has been placed in every row
if row == n:
res.append([list(row) for row in state])
return
# Traverse all columns
# Iterate over all columns
for col in range(n):
# Calculate the main diagonal and anti-diagonal corresponding to this cell
# Calculate the main-diagonal and anti-diagonal indices for this square
diag1 = row - col + n - 1
diag2 = row + col
# Pruning: do not allow queens to exist in the column, main diagonal, and anti-diagonal of this cell
# Prune: the square must have no queen in its column, main diagonal, or anti-diagonal
if not cols[col] and not diags1[diag1] and not diags2[diag2]:
# Attempt: place the queen in this cell
# Try: place a queen on this square
state[row][col] = "Q"
cols[col] = diags1[diag1] = diags2[diag2] = True
# Place the next row
# Place a queen in the next row
backtrack(row + 1, n, state, res, cols, diags1, diags2)
# Backtrack: restore this cell to an empty cell
# Backtrack: restore this square to empty
state[row][col] = "#"
cols[col] = diags1[diag1] = diags2[diag2] = False
def n_queens(n: int) -> list[list[list[str]]]:
"""Solve N queens"""
# Initialize an n*n chessboard, where 'Q' represents a queen and '#' represents an empty cell
"""Solve the n-queens problem"""
# Initialize an n*n board, where 'Q' represents a queen and '#' represents an empty square
state = [["#" for _ in range(n)] for _ in range(n)]
cols = [False] * n # Record whether there is a queen in the column
diags1 = [False] * (2 * n - 1) # Record whether there is a queen on the main diagonal
diags2 = [False] * (2 * n - 1) # Record whether there is a queen on the anti-diagonal
cols = [False] * n # Track whether a column contains a queen
diags1 = [False] * (2 * n - 1) # Track whether a main diagonal contains a queen
diags2 = [False] * (2 * n - 1) # Track whether an anti-diagonal contains a queen
res = []
backtrack(0, n, state, res, cols, diags1, diags2)
return res
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
n = 4
res = n_queens(n)
print(f"Input chessboard size is {n}")
print(f"There are {len(res)} queen placement solutions")
print(f"The input board has width and height {n}")
print(f"Number of ways to place the queens: {len(res)}")
for state in res:
print("--------------------")
for row in state:

View File

@@ -8,21 +8,21 @@ Author: krahets (krahets@163.com)
def backtrack(
state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]
):
"""Backtracking algorithm: Permutations I"""
# When the state length equals the number of elements, record the solution
"""Backtracking: permutations I"""
# Record a solution when the state length equals the number of elements
if len(state) == len(choices):
res.append(list(state))
return
# Traverse all choices
# Iterate over all choices
for i, choice in enumerate(choices):
# Pruning: do not allow repeated selection of elements
# Prune: do not choose an element more than once
if not selected[i]:
# Attempt: make choice, update state
# Try: make a choice and update the state
selected[i] = True
state.append(choice)
# Proceed to the next round of selection
# Proceed to the next choice
backtrack(state, choices, selected, res)
# Backtrack: undo choice, restore to previous state
# Backtrack: undo the choice and restore the previous state
selected[i] = False
state.pop()
@@ -34,11 +34,11 @@ def permutations_i(nums: list[int]) -> list[list[int]]:
return res
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
nums = [1, 2, 3]
res = permutations_i(nums)
print(f"Input array nums = {nums}")
print(f"All permutations res = {res}")
print(f"All permutations: res = {res}")

View File

@@ -8,23 +8,23 @@ Author: krahets (krahets@163.com)
def backtrack(
state: list[int], choices: list[int], selected: list[bool], res: list[list[int]]
):
"""Backtracking algorithm: Permutations II"""
# When the state length equals the number of elements, record the solution
"""Backtracking: permutations II"""
# Record a solution when the state length equals the number of elements
if len(state) == len(choices):
res.append(list(state))
return
# Traverse all choices
# Iterate over all choices
duplicated = set[int]()
for i, choice in enumerate(choices):
# Pruning: do not allow repeated selection of elements and do not allow repeated selection of equal elements
# Prune: do not reuse an element or choose the same value again at this depth
if not selected[i] and choice not in duplicated:
# Attempt: make choice, update state
duplicated.add(choice) # Record the selected element value
# Try: make a choice and update the state
duplicated.add(choice) # Record the chosen value
selected[i] = True
state.append(choice)
# Proceed to the next round of selection
# Proceed to the next choice
backtrack(state, choices, selected, res)
# Backtrack: undo choice, restore to previous state
# Backtrack: undo the choice and restore the previous state
selected[i] = False
state.pop()
@@ -36,11 +36,11 @@ def permutations_ii(nums: list[int]) -> list[list[int]]:
return res
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
nums = [1, 2, 2]
res = permutations_ii(nums)
print(f"Input array nums = {nums}")
print(f"All permutations res = {res}")
print(f"All permutations: res = {res}")

View File

@@ -12,20 +12,20 @@ from modules import TreeNode, print_tree, list_to_tree
def pre_order(root: TreeNode):
"""Preorder traversal: Example 1"""
"""Preorder traversal: example 1"""
if root is None:
return
if root.val == 7:
# Record solution
# Record the solution
res.append(root)
pre_order(root.left)
pre_order(root.right)
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
root = list_to_tree([1, 7, 3, 4, 5, 6, 7])
print("\nInitialize binary tree")
print("\nInitialize the binary tree")
print_tree(root)
# Preorder traversal

View File

@@ -12,13 +12,13 @@ from modules import TreeNode, print_tree, list_to_tree
def pre_order(root: TreeNode):
"""Preorder traversal: Example 2"""
"""Preorder traversal: example 2"""
if root is None:
return
# Attempt
# Try
path.append(root)
if root.val == 7:
# Record solution
# Record the solution
res.append(list(path))
pre_order(root.left)
pre_order(root.right)
@@ -26,10 +26,10 @@ def pre_order(root: TreeNode):
path.pop()
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
root = list_to_tree([1, 7, 3, 4, 5, 6, 7])
print("\nInitialize binary tree")
print("\nInitialize the binary tree")
print_tree(root)
# Preorder traversal
@@ -37,6 +37,6 @@ if __name__ == "__main__":
res = list[list[TreeNode]]()
pre_order(root)
print("\nOutput all paths from root node to node 7")
print("\nOutput all paths from the root to nodes with value 7")
for path in res:
print([node.val for node in path])

View File

@@ -12,14 +12,14 @@ from modules import TreeNode, print_tree, list_to_tree
def pre_order(root: TreeNode):
"""Preorder traversal: Example 3"""
# Pruning
"""Preorder traversal: example 3"""
# Prune
if root is None or root.val == 3:
return
# Attempt
# Try
path.append(root)
if root.val == 7:
# Record solution
# Record the solution
res.append(list(path))
pre_order(root.left)
pre_order(root.right)
@@ -27,10 +27,10 @@ def pre_order(root: TreeNode):
path.pop()
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
root = list_to_tree([1, 7, 3, 4, 5, 6, 7])
print("\nInitialize binary tree")
print("\nInitialize the binary tree")
print_tree(root)
# Preorder traversal
@@ -38,6 +38,6 @@ if __name__ == "__main__":
res = list[list[TreeNode]]()
pre_order(root)
print("\nOutput all paths from root node to node 7, excluding paths with nodes of value 3")
print("\nOutput all paths from the root to nodes with value 7 that contain no node with value 3")
for path in res:
print([node.val for node in path])

View File

@@ -12,60 +12,60 @@ from modules import TreeNode, print_tree, list_to_tree
def is_solution(state: list[TreeNode]) -> bool:
"""Check if the current state is a solution"""
"""Check whether the current state is a solution"""
return state and state[-1].val == 7
def record_solution(state: list[TreeNode], res: list[list[TreeNode]]):
"""Record solution"""
"""Record the solution"""
res.append(list(state))
def is_valid(state: list[TreeNode], choice: TreeNode) -> bool:
"""Check if the choice is valid under the current state"""
"""Check whether the choice is valid in the current state"""
return choice is not None and choice.val != 3
def make_choice(state: list[TreeNode], choice: TreeNode):
"""Update state"""
"""Update the state"""
state.append(choice)
def undo_choice(state: list[TreeNode], choice: TreeNode):
"""Restore state"""
"""Restore the state"""
state.pop()
def backtrack(
state: list[TreeNode], choices: list[TreeNode], res: list[list[TreeNode]]
):
"""Backtracking algorithm: Example 3"""
# Check if it is a solution
"""Backtracking: example 3"""
# Check whether this is a solution
if is_solution(state):
# Record solution
# Record the solution
record_solution(state, res)
# Traverse all choices
# Iterate over all choices
for choice in choices:
# Pruning: check if the choice is valid
# Prune: check whether the choice is valid
if is_valid(state, choice):
# Attempt: make choice, update state
# Try: make a choice and update the state
make_choice(state, choice)
# Proceed to the next round of selection
# Proceed to the next choice
backtrack(state, [choice.left, choice.right], res)
# Backtrack: undo choice, restore to previous state
# Backtrack: undo the choice and restore the previous state
undo_choice(state, choice)
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
root = list_to_tree([1, 7, 3, 4, 5, 6, 7])
print("\nInitialize binary tree")
print("\nInitialize the binary tree")
print_tree(root)
# Backtracking algorithm
res = []
backtrack(state=[], choices=[root], res=res)
print("\nOutput all paths from root node to node 7, excluding paths with nodes of value 3")
print("\nOutput all paths from the root to nodes with value 7, requiring that no node on the path has value 3")
for path in res:
print([node.val for node in path])

View File

@@ -8,23 +8,23 @@ Author: krahets (krahets@163.com)
def backtrack(
state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]
):
"""Backtracking algorithm: Subset sum I"""
# When the subset sum equals target, record the solution
"""Backtracking: subset sum I"""
# Record a solution when the remaining target is zero
if target == 0:
res.append(list(state))
return
# Traverse all choices
# Pruning 2: start traversing from start to avoid generating duplicate subsets
# Iterate over all choices
# Pruning 2: iterate from start to avoid generating duplicate subsets
for i in range(start, len(choices)):
# Pruning 1: if the subset sum exceeds target, end the loop directly
# This is because the array is sorted, and later elements are larger, so the subset sum will definitely exceed target
# Pruning 1: exit the loop if this choice exceeds the remaining target
# The array is sorted, so later elements are at least as large and also exceed the remaining target
if target - choices[i] < 0:
break
# Attempt: make choice, update target, start
# Try: make a choice and update target and start
state.append(choices[i])
# Proceed to the next round of selection
# Proceed to the next choice
backtrack(state, target - choices[i], choices, i, res)
# Backtrack: undo choice, restore to previous state
# Backtrack: undo the choice and restore the previous state
state.pop()
@@ -32,17 +32,17 @@ def subset_sum_i(nums: list[int], target: int) -> list[list[int]]:
"""Solve subset sum I"""
state = [] # State (subset)
nums.sort() # Sort nums
start = 0 # Start point for traversal
res = [] # Result list (subset list)
start = 0 # Starting index for iteration
res = [] # Result list (list of subsets)
backtrack(state, target, nums, start, res)
return res
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
nums = [3, 4, 5]
target = 9
res = subset_sum_i(nums, target)
print(f"Input array nums = {nums}, target = {target}")
print(f"All subsets with sum equal to {target} res = {res}")
print(f"All subsets with sum {target}: res = {res}")

View File

@@ -12,39 +12,39 @@ def backtrack(
choices: list[int],
res: list[list[int]],
):
"""Backtracking algorithm: Subset sum I"""
# When the subset sum equals target, record the solution
"""Backtracking: subset sum I"""
# Record a solution when the subset sum equals target
if total == target:
res.append(list(state))
return
# Traverse all choices
# Iterate over all choices
for i in range(len(choices)):
# Pruning: if the subset sum exceeds target, skip this choice
# Prune: skip this choice if the subset sum would exceed target
if total + choices[i] > target:
continue
# Attempt: make choice, update element sum total
# Try: make a choice and update the sum total
state.append(choices[i])
# Proceed to the next round of selection
# Proceed to the next choice
backtrack(state, target, total + choices[i], choices, res)
# Backtrack: undo choice, restore to previous state
# Backtrack: undo the choice and restore the previous state
state.pop()
def subset_sum_i_naive(nums: list[int], target: int) -> list[list[int]]:
"""Solve subset sum I (including duplicate subsets)"""
"""Solve subset sum I (with duplicate subsets)"""
state = [] # State (subset)
total = 0 # Subset sum
res = [] # Result list (subset list)
res = [] # Result list (list of subsets)
backtrack(state, target, total, nums, res)
return res
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
nums = [3, 4, 5]
target = 9
res = subset_sum_i_naive(nums, target)
print(f"Input array nums = {nums}, target = {target}")
print(f"All subsets with sum equal to {target} res = {res}")
print(f"Please note that the result output by this method contains duplicate sets")
print(f"All subsets with sum {target}: res = {res}")
print(f"Note that this method produces duplicate subsets")

View File

@@ -8,27 +8,27 @@ Author: krahets (krahets@163.com)
def backtrack(
state: list[int], target: int, choices: list[int], start: int, res: list[list[int]]
):
"""Backtracking algorithm: Subset sum II"""
# When the subset sum equals target, record the solution
"""Backtracking: subset sum II"""
# Record a solution when the remaining target is zero
if target == 0:
res.append(list(state))
return
# Traverse all choices
# Pruning 2: start traversing from start to avoid generating duplicate subsets
# Pruning 3: start traversing from start to avoid repeatedly selecting the same element
# Iterate over all choices
# Pruning 2: iterate from start to avoid generating duplicate subsets
# Pruning 3: start after the previously chosen index to avoid choosing the same element again
for i in range(start, len(choices)):
# Pruning 1: if the subset sum exceeds target, end the loop directly
# This is because the array is sorted, and later elements are larger, so the subset sum will definitely exceed target
# Pruning 1: exit the loop if this choice exceeds the remaining target
# The array is sorted, so later elements are at least as large and also exceed the remaining target
if target - choices[i] < 0:
break
# Pruning 4: if this element equals the left element, it means this search branch is duplicate, skip it directly
# Pruning 4: if this element equals its left neighbor at the same search depth, the branch is a duplicate; skip it
if i > start and choices[i] == choices[i - 1]:
continue
# Attempt: make choice, update target, start
# Try: make a choice and update target and start
state.append(choices[i])
# Proceed to the next round of selection
# Proceed to the next choice
backtrack(state, target - choices[i], choices, i + 1, res)
# Backtrack: undo choice, restore to previous state
# Backtrack: undo the choice and restore the previous state
state.pop()
@@ -36,17 +36,17 @@ def subset_sum_ii(nums: list[int], target: int) -> list[list[int]]:
"""Solve subset sum II"""
state = [] # State (subset)
nums.sort() # Sort nums
start = 0 # Start point for traversal
res = [] # Result list (subset list)
start = 0 # Starting index for iteration
res = [] # Result list (list of subsets)
backtrack(state, target, nums, start, res)
return res
"""Driver Code"""
"""Driver code"""
if __name__ == "__main__":
nums = [4, 4, 5]
target = 9
res = subset_sum_ii(nums, target)
print(f"Input array nums = {nums}, target = {target}")
print(f"All subsets with sum equal to {target} res = {res}")
print(f"All subsets with sum {target}: res = {res}")