Skip to content

Commit

Permalink
update backtrack cheatsheet, 090 py
Browse files Browse the repository at this point in the history
  • Loading branch information
yennanliu committed Oct 11, 2023
1 parent 1b01be3 commit 5684bcb
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 30 deletions.
96 changes: 67 additions & 29 deletions doc/cheatsheet/backtrack.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,35 @@

- Problems types

- `Subsets`
- LC 78, 140, 17
- Type 1) : `Subsets` (子集)
- Problems : LC 78, 90, 17
- [代碼隨想錄 - 0078.子集](https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0078.%E5%AD%90%E9%9B%86.md)
- (for loop call help func) + start_idx + for loop + pop(-1)
- backtrack. find minumum case. transform the problem to `tree-problem`. via `start` remove already used numbers and return all cases
- (for loop call help func) + for loop + pop(-1)
- "全排列"
```python
# V1
# ...
cur = []
res = []
def help(cur):
def help(start_idx, cur):
_cur = "".join(cur[:])
if _cur == s:
res.append(cur[:])
return
if len(_cur) > len(s):
cur = []
return
# NOTE !!! since we need get ALL sub group (全排列), so WE DON'T NEED deal with idx here
for i in range(len(wordDict)):
"""
NOTE !!! start_idx

we need start_idx here to AVOID re-select previous element
"""
for i in range(start_idx, len(wordDict)):
cur.append(wordDict[i])
help(cur)
help(start_idx+1, cur)
"""
NOTE !!! pop(-1)
"""
cur.pop(-1)
# ...
```
Expand All @@ -78,30 +85,61 @@
}
```

- `Subsets I`
- LC 78
- start idx + backtrack
```python
# python
class Solution:
def subsets(self, nums):
result = []
path = []
self.backtracking(nums, 0, path, result)
return result

def backtracking(self, nums, startIndex, path, result):
result.append(path[:]) # NOTE here
if startIndex >= len(nums): # optional
return
for i in range(startIndex, len(nums)): # NOTE here : we start from startIndex every time
path.append(nums[i])
self.backtracking(nums, i + 1, path, result) # NOTE here
path.pop(-1) # NOTE here
```

- `Subsets II`
- LC 90
```java
// java
// https://leetcode.com/problems/subsets/solutions/27281/a-general-approach-to-backtracking-questions-in-java-subsets-permutations-combination-sum-palindrome-partitioning/
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack(list, new ArrayList<>(), nums, 0);
return list;
}

private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
- start idx + backtrack + dedup (seen)
- dedup : can use dict counter or idx
```python
# python
from collections import Counter
class Solution:
def subsetsWithDup(self, nums):
result = []
path = []
# sort nums, so same element are in neighbor
nums.sort()
# NOTE : we use _cnt for record how count of element and used element
_cnt = Counter(nums)
self.backtracking(nums, 0, path, result, _cnt)
return result

def backtracking(self, nums, startIndex, path, result, _cnt):
if path not in result: # this line is optional
result.append(path[:]) # NOTE here
if startIndex >= len(nums): # optional
return
for i in range(startIndex, len(nums)): # NOTE here : we start from startIndex every time
if _cnt[nums[i]] > 0:
_cnt[nums[i]] -= 1
path.append(nums[i])
self.backtracking(nums, i + 1, path, result, _cnt) # NOTE here
path.pop(-1) # NOTE here
_cnt[nums[i]] += 1
```

- `Permutations (排列組合)`
- Type 2) : `Permutations (排列組合)`
- LC 46
- backtrack. via `contains` remove already used numbers and return all cases
- contains (visited) (or not in `cur`) + for loop + pop(-1) + help func
Expand Down Expand Up @@ -175,7 +213,7 @@
}
```

- `Combinations (組成)`
- Type 3) : `Combinations (組成)`
- LC 77
- backtrack. via `start` remove already used numbers and return all cases
- deal with `idx` !!! (start idx)
Expand Down
55 changes: 54 additions & 1 deletion leetcode_python/Backtracking/subsets-ii.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,34 @@
"""

# V0
# IDEA : BACKTRACKING + LC 078 Subsets
# IDEA : BACKTRACK + LC 078 Subsets + dict
from collections import Counter
class Solution:
def subsetsWithDup(self, nums):
result = []
path = []
# sort nums, so same element are in neighbor
nums.sort()
# NOTE : we use _cnt for record how count of element and used element
_cnt = Counter(nums)
self.backtracking(nums, 0, path, result, _cnt)
return result

def backtracking(self, nums, startIndex, path, result, _cnt):
if path not in result: # this line is optional
result.append(path[:]) # NOTE here
if startIndex >= len(nums): # optional
return
for i in range(startIndex, len(nums)): # NOTE here : we start from startIndex every time
if _cnt[nums[i]] > 0:
_cnt[nums[i]] -= 1
path.append(nums[i])
self.backtracking(nums, i + 1, path, result, _cnt) # NOTE here
path.pop(-1) # NOTE here
_cnt[nums[i]] += 1

# V0'
# IDEA : BACKTRACKING + LC 078 Subsets + dict
from collections import Counter
class Solution(object):
def subsetsWithDup(self, nums):
Expand Down Expand Up @@ -65,6 +92,32 @@ def help(start, tmp, _cnt):
print ("res = " + str(res))
return res

# V0''''
# IDEA : backtrack + seen
# https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0090.%E5%AD%90%E9%9B%86II.md
class Solution:
def subsetsWithDup(self, nums):
result = []
path = []
used = [False] * len(nums)
nums.sort() # 去重需要排序
self.backtracking(nums, 0, used, path, result)
return result

def backtracking(self, nums, startIndex, used, path, result):
result.append(path[:]) # 收集子集
for i in range(startIndex, len(nums)):
# used[i - 1] == True,说明同一树枝 nums[i - 1] 使用过
# used[i - 1] == False,说明同一树层 nums[i - 1] 使用过
# 而我们要对同一树层使用过的元素进行跳过
if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:
continue
path.append(nums[i])
used[i] = True
self.backtracking(nums, i + 1, used, path, result)
used[i] = False
path.pop()

# V0'
# IDEA : BRUTE FORCE
class Solution:
Expand Down

0 comments on commit 5684bcb

Please sign in to comment.