Skip to content

2025/03/28 #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Hard/140 Word Break II.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# 140. Work Break II

## Intuition

We need to explore all possible combinations of words that can form the input string. This naturally leads to a recursive approach where we try different word combinations at each step.

## Approach

1. First, we create a map of valid words from the dictionary for O(1) lookup.
2. We use a recursive function that:
- Builds the current word character by character
- When a valid word is found, we have two choices:
a. Add the word to our current path and start a new word
b. Continue building the current word
3. When we reach the end of the string with a valid word, we join all words in the current path with spaces and add it to our result.
4. The recursion explores all possible combinations of words that can form the input string.

## Complexity

- Time complexity: O(2^n)
- Space complexity: O(n)

## Keywords

- Recursion
- Backtracking
- DFS

## Code

```go
func wordBreak(s string, wordDict []string) []string {
ret, wordMap := make([]string, 0), make(map[string]bool)
for _, word := range wordDict {
wordMap[word] = true
}

var recur func(curI int, curWord string, curStr []string)
recur = func(curI int, curWord string, curStr []string) {
if curI == len(s) {
return
}
curWord += string(s[curI])
if wordMap[curWord] {
tmp := make([]string, len(curStr))
copy(tmp, curStr)
tmp = append(tmp, curWord)
if curI == len(s) - 1 {
retStr := strings.Join(tmp, " ")
ret = append(ret, retStr)
} else {
recur(curI + 1, "", tmp)
}
}
recur(curI + 1, curWord, curStr)
}

recur(0, "", make([]string, 0))
return ret
}
```
83 changes: 83 additions & 0 deletions Hard/51 N-Queens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 51. N-Queens

## Intuition

The key insight is that queens can attack horizontally, vertically, and diagonally. We need to ensure that no two queens share the same row, column, or diagonal.

## Approach

1. Use backtracking to explore all possible queen placements
2. Maintain three sets to track occupied rows, columns, and diagonals
3. For each row, try placing a queen in each column if it's safe
4. If a valid placement is found, recursively try the next row
5. If we reach the last row successfully, add the current board configuration to the result
6. Backtrack by removing the last placed queen and try the next position

## Complexity

- Time complexity: O(N!)
- Space complexity: O(N)

## Keywords

- Backtracking
- Recursion
- N-Queens
- DFS

## Code

```go
func solveNQueens(n int) [][]string {
ret, board, queens := make([][]string, 0), make([]string, n), make([][2]int, 0)
row := ""
for i := 0; i < n; i += 1 {
row += "."
}
for i := range board {
board[i] = row
}
rowMap, colMap := make(map[int]bool, n), make(map[int]bool, n)
var checkq func(i, j int) bool
var replaceQ func(i, j int)
var revertQ func(i, j int)
var recursion func(level int)
checkq = func(i, j int) bool {
for _, queen := range queens {
if math.Abs(float64(queen[0] - i) / float64(queen[1] - j)) == 1 {
return false
}
}
return true
}
replaceQ = func(i, j int) {
tmp := []byte(board[i])
tmp[j] = 'Q'
board[i] = string(tmp)
}
revertQ = func(i, j int) {
tmp := []byte(board[i])
tmp[j] = '.'
board[i] = string(tmp)
}
recursion = func(level int) {
for i := 0; i < n; i += 1 {
if !rowMap[level] && !colMap[i] && checkq(level, i) {
replaceQ(level, i)
rowMap[level], colMap[i] = true, true
queens = append(queens, [2]int{level, i})
if level == n - 1 {
ret = append(ret, append([]string{}, board...))
} else {
recursion(level + 1)
}
revertQ(level, i)
rowMap[level], colMap[i] = false, false
queens = queens[: len(queens) - 1]
}
}
}
recursion(0)
return ret
}
```
47 changes: 47 additions & 0 deletions Medium/46 Permutations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 46. Permutations

## Intuition

The key insight is that we can build permutations recursively by selecting each number as the first element and then generating permutations for the remaining numbers.

## Approach

1. Use a recursive backtracking approach
2. For each recursive call:
- If there are no numbers left to permute, add the current permutation to the result
- Otherwise, iterate through the remaining numbers
- For each number, create a new permutation by adding it to the current permutation
- Recursively call the function with the remaining numbers (excluding the current number)
3. The base case is when there are no numbers left to permute

## Complexity

- Time complexity: O(n * n!)
- Space complexity: O(n * n!)

## Keywords

- Backtracking
- Recursion
- Permutation

## Code

```go
func recursion(cur, nums []int, ret *[][]int) {
if len(nums) == 0 {
*ret = append(*ret, cur)
return
}
for i, num := range nums {
cp := make([]int, len(nums))
copy(cp, nums)
recursion(append(cur, num), append(cp[:i], cp[i + 1:]...), ret)
}
}
func permute(nums []int) [][]int {
ret := make([][]int, 0)
recursion([]int{}, nums, &ret)
return ret
}
```
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
| 24 | Swap Nodes in Pairs | [go](/Medium/24%20Swap%20Nodes%20in%20Pairs.md) | M |
| 25 | Reverse Nodes in k-Group | [go](/Hard/25%20Reverse%20Nodes%20in%20k-Group.md) | H |
| 45 | Jump Game II | [go](/Medium/45%20Jump%20Game%20II.md) | M |
| 46 | Permutations | [go](/Medium/46%20Permutations.md) | M |
| 50 | Pow(x, n) | [go](/Medium/50%20Pow(x,%20n).md) | M |
| 51 | N-Queens | [go](/Hard/51%20N-Queens.md) | H |
| 105 | Construct Binary Tree from Preorder and Inorder Tranversal | [go](/Medium/105%20Construct%20Binary%20Tree%20from%20Preorder%20and%20Inorder%20Tranversal.md) | M |
| 135 | Candy | [go](/Hard/135%20Candy.md) | H |
| 140 | Word Break II | [go](/Hard/140%20Word%20Break%20II.md) | H |
| 146 | LRU Cache | [go](/Medium/146%20LRU%20Cache.md) | M |
| 239 | Sliding Window Maximum | [go](/Hard/239%20Sliding%20Window%20Maximum.md) | H |
| 460 | LFU Cache | [go](/Hard/460%20LFU%20Cache.md) | H |
Expand Down
Binary file added Week6/140 AC.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions Week6/140 Word Break II.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# 140. Work Break II

## Intuition

We need to explore all possible combinations of words that can form the input string. This naturally leads to a recursive approach where we try different word combinations at each step.

## Approach

1. First, we create a map of valid words from the dictionary for O(1) lookup.
2. We use a recursive function that:
- Builds the current word character by character
- When a valid word is found, we have two choices:
a. Add the word to our current path and start a new word
b. Continue building the current word
3. When we reach the end of the string with a valid word, we join all words in the current path with spaces and add it to our result.
4. The recursion explores all possible combinations of words that can form the input string.

## Complexity

- Time complexity: O(2^n)
- Space complexity: O(n)

## Keywords

- Recursion
- Backtracking
- DFS

## Code

```go
func wordBreak(s string, wordDict []string) []string {
ret, wordMap := make([]string, 0), make(map[string]bool)
for _, word := range wordDict {
wordMap[word] = true
}

var recur func(curI int, curWord string, curStr []string)
recur = func(curI int, curWord string, curStr []string) {
if curI == len(s) {
return
}
curWord += string(s[curI])
if wordMap[curWord] {
tmp := make([]string, len(curStr))
copy(tmp, curStr)
tmp = append(tmp, curWord)
if curI == len(s) - 1 {
retStr := strings.Join(tmp, " ")
ret = append(ret, retStr)
} else {
recur(curI + 1, "", tmp)
}
}
recur(curI + 1, curWord, curStr)
}

recur(0, "", make([]string, 0))
return ret
}
```
Binary file added Week6/46 AC.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions Week6/46 Permutations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 46. Permutations

## Intuition

The key insight is that we can build permutations recursively by selecting each number as the first element and then generating permutations for the remaining numbers.

## Approach

1. Use a recursive backtracking approach
2. For each recursive call:
- If there are no numbers left to permute, add the current permutation to the result
- Otherwise, iterate through the remaining numbers
- For each number, create a new permutation by adding it to the current permutation
- Recursively call the function with the remaining numbers (excluding the current number)
3. The base case is when there are no numbers left to permute

## Complexity

- Time complexity: O(n * n!)
- Space complexity: O(n * n!)

## Keywords

- Backtracking
- Recursion
- Permutation

## Code

```go
func recursion(cur, nums []int, ret *[][]int) {
if len(nums) == 0 {
*ret = append(*ret, cur)
return
}
for i, num := range nums {
cp := make([]int, len(nums))
copy(cp, nums)
recursion(append(cur, num), append(cp[:i], cp[i + 1:]...), ret)
}
}
func permute(nums []int) [][]int {
ret := make([][]int, 0)
recursion([]int{}, nums, &ret)
return ret
}
```
Binary file added Week6/51 AC.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading