mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -130,10 +130,10 @@ class Solution:
|
|||||||
head_dummy.next = head
|
head_dummy.next = head
|
||||||
|
|
||||||
slow, fast = head_dummy, head_dummy
|
slow, fast = head_dummy, head_dummy
|
||||||
while(n!=0): #fast先往前走n步
|
while(n>=0): #fast先往前走n+1步
|
||||||
fast = fast.next
|
fast = fast.next
|
||||||
n -= 1
|
n -= 1
|
||||||
while(fast.next!=None):
|
while(fast!=None):
|
||||||
slow = slow.next
|
slow = slow.next
|
||||||
fast = fast.next
|
fast = fast.next
|
||||||
#fast 走到结尾后,slow的下一个节点为倒数第N个节点
|
#fast 走到结尾后,slow的下一个节点为倒数第N个节点
|
||||||
|
@ -117,6 +117,9 @@ public:
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* 时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
|
||||||
|
* 空间复杂度 O(1)
|
||||||
|
|
||||||
## 类似题目
|
## 类似题目
|
||||||
|
|
||||||
* 54.螺旋矩阵
|
* 54.螺旋矩阵
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* 转换过程中的中间单词必须是字典 wordList 中的单词。
|
* 转换过程中的中间单词必须是字典 wordList 中的单词。
|
||||||
* 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。
|
* 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。
|
||||||
|
|
||||||
|
|
||||||
示例 1:
|
示例 1:
|
||||||
|
|
||||||
* 输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
|
* 输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
|
||||||
@ -134,7 +134,70 @@ public int ladderLength(String beginWord, String endWord, List<String> wordList)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Java 双向BFS
|
||||||
|
class Solution {
|
||||||
|
// 判断单词之间是否之差了一个字母
|
||||||
|
public boolean isValid(String currentWord, String chooseWord) {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < currentWord.length(); i++)
|
||||||
|
if (currentWord.charAt(i) != chooseWord.charAt(i)) ++count;
|
||||||
|
return count == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
|
||||||
|
if (!wordList.contains(endWord)) return 0; // 如果 endWord 不在 wordList 中,那么无法成功转换,返回 0
|
||||||
|
|
||||||
|
// ansLeft 记录从 beginWord 开始 BFS 时能组成的单词数目
|
||||||
|
// ansRight 记录从 endWord 开始 BFS 时能组成的单词数目
|
||||||
|
int ansLeft = 0, ansRight = 0;
|
||||||
|
|
||||||
|
// queueLeft 表示从 beginWord 开始 BFS 时使用的队列
|
||||||
|
// queueRight 表示从 endWord 开始 BFS 时使用的队列
|
||||||
|
Queue<String> queueLeft = new ArrayDeque<>(), queueRight = new ArrayDeque<>();
|
||||||
|
queueLeft.add(beginWord);
|
||||||
|
queueRight.add(endWord);
|
||||||
|
|
||||||
|
// 从 beginWord 开始 BFS 时把遍历到的节点存入 hashSetLeft 中
|
||||||
|
// 从 endWord 开始 BFS 时把遍历到的节点存入 hashSetRight 中
|
||||||
|
Set<String> hashSetLeft = new HashSet<>(), hashSetRight = new HashSet<>();
|
||||||
|
hashSetLeft.add(beginWord);
|
||||||
|
hashSetRight.add(endWord);
|
||||||
|
|
||||||
|
// 只要有一个队列为空,说明 beginWord 无法转换到 endWord
|
||||||
|
while (!queueLeft.isEmpty() && !queueRight.isEmpty()) {
|
||||||
|
++ansLeft;
|
||||||
|
int size = queueLeft.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
String currentWord = queueLeft.poll();
|
||||||
|
// 只要 hashSetRight 中存在 currentWord,说明从 currentWord 可以转换到 endWord
|
||||||
|
if (hashSetRight.contains(currentWord)) return ansRight + ansLeft;
|
||||||
|
for (String chooseWord : wordList) {
|
||||||
|
if (hashSetLeft.contains(chooseWord) || !isValid(currentWord, chooseWord)) continue;
|
||||||
|
hashSetLeft.add(chooseWord);
|
||||||
|
queueLeft.add(chooseWord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++ansRight;
|
||||||
|
size = queueRight.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
String currentWord = queueRight.poll();
|
||||||
|
// 只要 hashSetLeft 中存在 currentWord,说明从 currentWord 可以转换到 beginWord
|
||||||
|
if (hashSetLeft.contains(currentWord)) return ansLeft + ansRight;
|
||||||
|
for (String chooseWord : wordList) {
|
||||||
|
if (hashSetRight.contains(chooseWord) || !isValid(currentWord, chooseWord)) continue;
|
||||||
|
hashSetRight.add(chooseWord);
|
||||||
|
queueRight.add(chooseWord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
|
||||||
```
|
```
|
||||||
class Solution:
|
class Solution:
|
||||||
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
|
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
|
||||||
@ -301,3 +364,4 @@ function diffonechar(word1: string, word2: string): boolean {
|
|||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -143,9 +143,9 @@ class Solution {
|
|||||||
return resSet.stream().mapToInt(x -> x).toArray();
|
return resSet.stream().mapToInt(x -> x).toArray();
|
||||||
|
|
||||||
//方法2:另外申请一个数组存放setRes中的元素,最后返回数组
|
//方法2:另外申请一个数组存放setRes中的元素,最后返回数组
|
||||||
int[] arr = new int[setRes.size()];
|
int[] arr = new int[resSet.size()];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for(int i : setRes){
|
for(int i : resSet){
|
||||||
arr[j++] = i;
|
arr[j++] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,21 +462,43 @@ var wiggleMaxLength = function(nums) {
|
|||||||
```Rust
|
```Rust
|
||||||
impl Solution {
|
impl Solution {
|
||||||
pub fn wiggle_max_length(nums: Vec<i32>) -> i32 {
|
pub fn wiggle_max_length(nums: Vec<i32>) -> i32 {
|
||||||
let len = nums.len() as usize;
|
if nums.len() == 1 {
|
||||||
if len <= 1 {
|
return 1;
|
||||||
return len as i32;
|
|
||||||
}
|
}
|
||||||
let mut preDiff = 0;
|
let mut res = 1;
|
||||||
let mut curDiff = 0;
|
let mut pre_diff = 0;
|
||||||
let mut result = 1;
|
for i in 0..nums.len() - 1 {
|
||||||
for i in 0..len-1 {
|
let cur_diff = nums[i + 1] - nums[i];
|
||||||
curDiff = nums[i+1] - nums[i];
|
if (pre_diff <= 0 && cur_diff > 0) || (pre_diff >= 0 && cur_diff < 0) {
|
||||||
if (preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0) {
|
res += 1;
|
||||||
result += 1;
|
pre_diff = cur_diff;
|
||||||
preDiff = curDiff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**动态规划**
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Solution {
|
||||||
|
pub fn wiggle_max_length(nums: Vec<i32>) -> i32 {
|
||||||
|
if nums.len() == 1 {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let (mut down, mut up) = (1, 1);
|
||||||
|
for i in 1..nums.len() {
|
||||||
|
// i - 1 为峰顶
|
||||||
|
if nums[i] < nums[i - 1] {
|
||||||
|
down = down.max(up + 1);
|
||||||
|
}
|
||||||
|
// i - 1 为峰谷
|
||||||
|
if nums[i] > nums[i - 1] {
|
||||||
|
up = up.max(down + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
down.max(up)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -303,7 +303,7 @@ class Solution:
|
|||||||
target = sum(nums)
|
target = sum(nums)
|
||||||
if target % 2 == 1: return False
|
if target % 2 == 1: return False
|
||||||
target //= 2
|
target //= 2
|
||||||
dp = [0] * (len(nums) + 1)
|
dp = [0] * (target + 1)
|
||||||
for i in range(len(nums)):
|
for i in range(len(nums)):
|
||||||
for j in range(target, nums[i] - 1, -1):
|
for j in range(target, nums[i] - 1, -1):
|
||||||
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
|
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
|
||||||
|
@ -219,19 +219,17 @@ func findContentChildren(g []int, s []int) int {
|
|||||||
|
|
||||||
### Rust
|
### Rust
|
||||||
```rust
|
```rust
|
||||||
pub fn find_content_children(children: Vec<i32>, cookie: Vec<i32>) -> i32 {
|
pub fn find_content_children(mut children: Vec<i32>, mut cookie: Vec<i32>) -> i32 {
|
||||||
let mut children = children;
|
|
||||||
let mut cookies = cookie;
|
|
||||||
children.sort();
|
children.sort();
|
||||||
cookies.sort();
|
cookies.sort();
|
||||||
|
|
||||||
let (mut child, mut cookie) = (0usize, 0usize);
|
let (mut child, mut cookie) = (0, 0);
|
||||||
while child < children.len() && cookie < cookies.len() {
|
while child < children.len() && cookie < cookies.len() {
|
||||||
// 优先选择最小饼干喂饱孩子
|
// 优先选择最小饼干喂饱孩子
|
||||||
if children[child] <= cookies[cookie] {
|
if children[child] <= cookies[cookie] {
|
||||||
child += 1;
|
child += 1;
|
||||||
}
|
}
|
||||||
cookie += 1
|
cookie += 1;
|
||||||
}
|
}
|
||||||
child as i32
|
child as i32
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
```
|
```
|
||||||
|
* 时间复杂度:O(log n)
|
||||||
|
* 空间复杂度:O(1)
|
||||||
|
|
||||||
|
|
||||||
### 二分法第二种写法
|
### 二分法第二种写法
|
||||||
|
|
||||||
@ -125,6 +128,9 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
* 时间复杂度:O(log n)
|
||||||
|
* 空间复杂度:O(1)
|
||||||
|
|
||||||
|
|
||||||
## 总结
|
## 总结
|
||||||
|
|
||||||
|
@ -219,7 +219,71 @@ public:
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# 其他语言版本
|
||||||
|
|
||||||
|
## Java
|
||||||
|
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 四个方向
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param grid 矩阵数组
|
||||||
|
* @param row 当前遍历的节点的行号
|
||||||
|
* @param col 当前遍历的节点的列号
|
||||||
|
* @param mark 当前区域的标记
|
||||||
|
* @return 返回当前区域内 1 的数量
|
||||||
|
*/
|
||||||
|
public int dfs(int[][] grid, int row, int col, int mark) {
|
||||||
|
int ans = 0;
|
||||||
|
grid[row][col] = mark;
|
||||||
|
for (int[] current: position) {
|
||||||
|
int curRow = row + current[0], curCol = col + current[1];
|
||||||
|
if (curRow < 0 || curRow >= grid.length || curCol < 0 || curCol >= grid.length) continue; // 越界
|
||||||
|
if (grid[curRow][curCol] == 1)
|
||||||
|
ans += 1 + dfs(grid, curRow, curCol, mark);
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int largestIsland(int[][] grid) {
|
||||||
|
int ans = Integer.MIN_VALUE, size = grid.length, mark = 2;
|
||||||
|
Map<Integer, Integer> getSize = new HashMap<>();
|
||||||
|
for (int row = 0; row < size; row++) {
|
||||||
|
for (int col = 0; col < size; col++) {
|
||||||
|
if (grid[row][col] == 1) {
|
||||||
|
int areaSize = 1 + dfs(grid, row, col, mark);
|
||||||
|
getSize.put(mark++, areaSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int row = 0; row < size; row++) {
|
||||||
|
for (int col = 0; col < size; col++) {
|
||||||
|
// 当前位置如果不是 0 那么直接跳过,因为我们只能把 0 变成 1
|
||||||
|
if (grid[row][col] != 0) continue;
|
||||||
|
Set<Integer> hashSet = new HashSet<>(); // 防止同一个区域被重复计算
|
||||||
|
// 计算从当前位置开始获取的 1 的数量,初始化 1 是因为把当前位置的 0 转换成了 1
|
||||||
|
int curSize = 1;
|
||||||
|
for (int[] current: position) {
|
||||||
|
int curRow = row + current[0], curCol = col + current[1];
|
||||||
|
if (curRow < 0 || curRow >= grid.length || curCol < 0 || curCol >= grid.length) continue;
|
||||||
|
int curMark = grid[curRow][curCol]; // 获取对应位置的标记
|
||||||
|
// 如果标记存在 hashSet 中说明该标记被记录过一次,如果不存在 getSize 中说明该标记是无效标记(此时 curMark = 0)
|
||||||
|
if (hashSet.contains(curMark) || !getSize.containsKey(curMark)) continue;
|
||||||
|
hashSet.add(curMark);
|
||||||
|
curSize += getSize.get(curMark);
|
||||||
|
}
|
||||||
|
ans = Math.max(ans, curSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 当 ans == Integer.MIN_VALUE 说明矩阵数组中不存在 0,全都是有效区域,返回数组大小即可
|
||||||
|
return ans == Integer.MIN_VALUE ? size * size : ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -275,6 +275,52 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```Java
|
||||||
|
// 广度优先搜索
|
||||||
|
class Solution {
|
||||||
|
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
|
||||||
|
boolean[] visited = new boolean[rooms.size()]; // 用一个 visited 数据记录房间是否被访问
|
||||||
|
visited[0] = true;
|
||||||
|
Queue<Integer> queue = new ArrayDeque<>();
|
||||||
|
queue.add(0); // 第 0 个房间标记为已访问
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
int curKey = queue.poll();
|
||||||
|
for (int key: rooms.get(curKey)) {
|
||||||
|
if (visited[key]) continue;
|
||||||
|
visited[key] = true;
|
||||||
|
queue.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (boolean key: visited)
|
||||||
|
if (!key) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 广度优先遍历(时间优化)
|
||||||
|
class Solution {
|
||||||
|
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
|
||||||
|
int count = 1; // 用来记录可以被访问的房间数目,因为初始状态下 0 号房间可以被访问,所以置为 1
|
||||||
|
boolean[] visited = new boolean[rooms.size()]; // 用一个 visited 数据记录房间是否被访问
|
||||||
|
visited[0] = true; // 第 0 个房间标记为已访问
|
||||||
|
Queue<Integer> queue = new ArrayDeque<>();
|
||||||
|
queue.add(0);
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
int curKey = queue.poll();
|
||||||
|
for (int key: rooms.get(curKey)) {
|
||||||
|
if (visited[key]) continue;
|
||||||
|
++count; // 每访问一个访问房间就让 count 加 1
|
||||||
|
visited[key] = true;
|
||||||
|
queue.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count == rooms.size(); // 如果 count 等于房间数目,表示能进入所有房间,反之不能
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### python3
|
### python3
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -305,11 +305,12 @@ def construct_binary_tree(nums: []) -> TreeNode:
|
|||||||
Tree.append(node)
|
Tree.append(node)
|
||||||
if i == 0:
|
if i == 0:
|
||||||
root = node
|
root = node
|
||||||
|
# 直接判断2*i+2<len(Tree)会漏掉2*i+1=len(Tree)-1的情况
|
||||||
for i in range(len(Tree)):
|
for i in range(len(Tree)):
|
||||||
node = Tree[i]
|
if Tree[i] and 2 * i + 1 < len(Tree):
|
||||||
if node and (2 * i + 2) < len(Tree):
|
Tree[i].left = Tree[2 * i + 1]
|
||||||
node.left = Tree[i * 2 + 1]
|
if 2 * i + 2 < len(Tree):
|
||||||
node.right = Tree[i * 2 + 2]
|
Tree[i].right = Tree[2 * i + 2]
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ for (int i = 3; i <= n ; i++) {
|
|||||||
|
|
||||||
其实可以模拟一下哈,拆分j的情况,在遍历j的过程中dp[i - j]其实都计算过了。
|
其实可以模拟一下哈,拆分j的情况,在遍历j的过程中dp[i - j]其实都计算过了。
|
||||||
|
|
||||||
例如 i= 10,j = 5,i-j = 5,如果把j查分为 2 和 3,其实在j = 2 的时候,i-j= 8 ,拆分i-j的时候就可以拆出来一个3了。
|
例如 i= 10,j = 5,i-j = 5,如果把j拆分为 2 和 3,其实在j = 2 的时候,i-j= 8 ,拆分i-j的时候就可以拆出来一个3了。
|
||||||
|
|
||||||
**或者也可以理解j是拆分i的第一个整数**。
|
**或者也可以理解j是拆分i的第一个整数**。
|
||||||
|
|
||||||
|
@ -526,10 +526,122 @@ function permuteUnique(nums: number[]): number[][] {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
Rust:
|
||||||
|
|
||||||
|
**90.子集II**:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use std::collections::HashSet;
|
||||||
|
impl Solution {
|
||||||
|
pub fn subsets_with_dup(mut nums: Vec<i32>) -> Vec<Vec<i32>> {
|
||||||
|
let mut res = vec![];
|
||||||
|
let mut path = vec![];
|
||||||
|
nums.sort();
|
||||||
|
Self::backtracking(&nums, &mut path, &mut res, 0);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn backtracking(
|
||||||
|
nums: &Vec<i32>,
|
||||||
|
path: &mut Vec<i32>,
|
||||||
|
res: &mut Vec<Vec<i32>>,
|
||||||
|
start_index: usize,
|
||||||
|
) {
|
||||||
|
res.push(path.clone());
|
||||||
|
let mut helper_set = HashSet::new();
|
||||||
|
for i in start_index..nums.len() {
|
||||||
|
if helper_set.contains(&nums[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
helper_set.insert(nums[i]);
|
||||||
|
path.push(nums[i]);
|
||||||
|
Self::backtracking(nums, path, res, i + 1);
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**40. 组合总和 II**
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use std::collections::HashSet;
|
||||||
|
impl Solution {
|
||||||
|
pub fn backtracking(
|
||||||
|
candidates: &Vec<i32>,
|
||||||
|
target: i32,
|
||||||
|
sum: i32,
|
||||||
|
path: &mut Vec<i32>,
|
||||||
|
res: &mut Vec<Vec<i32>>,
|
||||||
|
start_index: usize,
|
||||||
|
) {
|
||||||
|
if sum > target {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if sum == target {
|
||||||
|
res.push(path.clone());
|
||||||
|
}
|
||||||
|
let mut helper_set = HashSet::new();
|
||||||
|
for i in start_index..candidates.len() {
|
||||||
|
if sum + candidates[i] <= target {
|
||||||
|
if helper_set.contains(&candidates[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
helper_set.insert(candidates[i]);
|
||||||
|
path.push(candidates[i]);
|
||||||
|
Self::backtracking(candidates, target, sum + candidates[i], path, res, i + 1);
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn combination_sum2(mut candidates: Vec<i32>, target: i32) -> Vec<Vec<i32>> {
|
||||||
|
let mut res = vec![];
|
||||||
|
let mut path = vec![];
|
||||||
|
candidates.sort();
|
||||||
|
Self::backtracking(&candidates, target, 0, &mut path, &mut res, 0);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**47. 全排列 II**
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use std::collections::HashSet;
|
||||||
|
impl Solution {
|
||||||
|
pub fn permute_unique(mut nums: Vec<i32>) -> Vec<Vec<i32>> {
|
||||||
|
let mut res = vec![];
|
||||||
|
let mut path = vec![];
|
||||||
|
let mut used = vec![false; nums.len()];
|
||||||
|
Self::backtracking(&mut res, &mut path, &nums, &mut used);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
pub fn backtracking(
|
||||||
|
res: &mut Vec<Vec<i32>>,
|
||||||
|
path: &mut Vec<i32>,
|
||||||
|
nums: &Vec<i32>,
|
||||||
|
used: &mut Vec<bool>,
|
||||||
|
) {
|
||||||
|
if path.len() == nums.len() {
|
||||||
|
res.push(path.clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut helper_set = HashSet::new();
|
||||||
|
for i in 0..nums.len() {
|
||||||
|
if used[i] || helper_set.contains(&nums[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
helper_set.insert(nums[i]);
|
||||||
|
path.push(nums[i]);
|
||||||
|
used[i] = true;
|
||||||
|
Self::backtracking(res, path, nums, used);
|
||||||
|
used[i] = false;
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
|
Reference in New Issue
Block a user