From f7391d3c9e7cb051ca3f0a58daedb2d4b6f62b79 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sun, 17 Dec 2023 16:40:27 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.0090 No.0090.Subsets II --- .../0000-0099/0038.Count and Say/Solution.rs | 43 ++- .../0000-0099/0065.Valid Number/README.md | 11 +- solution/0000-0099/0090.Subsets II/README.md | 322 ++++++++++++++---- .../0000-0099/0090.Subsets II/README_EN.md | 322 ++++++++++++++---- .../0000-0099/0090.Subsets II/Solution.cpp | 43 +-- .../0000-0099/0090.Subsets II/Solution.go | 30 +- .../0000-0099/0090.Subsets II/Solution.java | 46 +-- .../0000-0099/0090.Subsets II/Solution.py | 32 +- .../0000-0099/0090.Subsets II/Solution.rs | 38 ++- .../0000-0099/0090.Subsets II/Solution.ts | 31 +- 10 files changed, 653 insertions(+), 265 deletions(-) diff --git a/solution/0000-0099/0038.Count and Say/Solution.rs b/solution/0000-0099/0038.Count and Say/Solution.rs index e6a11b4d3ffaf..771fb88260526 100644 --- a/solution/0000-0099/0038.Count and Say/Solution.rs +++ b/solution/0000-0099/0038.Count and Say/Solution.rs @@ -1,22 +1,21 @@ -use std::iter::once; - -impl Solution { - pub fn count_and_say(n: i32) -> String { - (1..n) - .fold(vec![1], |curr, _| { - let mut next = vec![]; - let mut slow = 0; - for fast in 0..=curr.len() { - if fast == curr.len() || curr[slow] != curr[fast] { - next.extend(once((fast - slow) as u8).chain(once(curr[slow]))); - slow = fast; - } - } - next - }) - .into_iter() - .map(|digit| (digit + b'0') as char) - .collect() - } -} - +use std::iter::once; + +impl Solution { + pub fn count_and_say(n: i32) -> String { + (1..n) + .fold(vec![1], |curr, _| { + let mut next = vec![]; + let mut slow = 0; + for fast in 0..=curr.len() { + if fast == curr.len() || curr[slow] != curr[fast] { + next.extend(once((fast - slow) as u8).chain(once(curr[slow]))); + slow = fast; + } + } + next + }) + .into_iter() + .map(|digit| (digit + b'0') as char) + .collect() + } +} diff --git a/solution/0000-0099/0065.Valid Number/README.md b/solution/0000-0099/0065.Valid Number/README.md index a702e9d577960..1b0b9a108516e 100644 --- a/solution/0000-0099/0065.Valid Number/README.md +++ b/solution/0000-0099/0065.Valid Number/README.md @@ -277,13 +277,10 @@ impl Solution { } } if let Some(x) = s.chars().nth(i) { - if x == '.' - && (i + 1 == n - || if let Some(m) = s.chars().nth(i + 1) { - m == 'e' || m == 'E' - } else { - false - }) + if + x == '.' && + (i + 1 == n || + (if let Some(m) = s.chars().nth(i + 1) { m == 'e' || m == 'E' } else { false })) { return false; } diff --git a/solution/0000-0099/0090.Subsets II/README.md b/solution/0000-0099/0090.Subsets II/README.md index 632d684de96ea..abc5ddc3de256 100644 --- a/solution/0000-0099/0090.Subsets II/README.md +++ b/solution/0000-0099/0090.Subsets II/README.md @@ -43,6 +43,30 @@ +**方法一:排序 + DFS** + +我们可以先对数组 $nums$ 进行排序,方便去重。 + +然后,我们设计一个函数 $dfs(i)$,表示当前从第 $i$ 个元素开始搜索子集。函数 $dfs(i)$ 的执行逻辑如下: + +如果 $i \geq n$,说明已经搜索完所有元素,将当前子集加入答案数组中,递归结束。 + +如果 $i < n$,将第 $i$ 个元素加入子集,执行 $dfs(i + 1)$,然后将第 $i$ 个元素从子集中移除。接下来,我们判断第 $i$ 个元素是否和下一个元素相同,如果相同,则循环跳过该元素,直到找到第一个和第 $i$ 个元素不同的元素,执行 $dfs(i + 1)$。 + +最后,我们只需要调用 $dfs(0)$,返回答案数组即可。 + +时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + +**方法二:排序 + 二进制枚举** + +与方法一类似,我们先对数组 $nums$ 进行排序,方便去重。 + +接下来,我们在 $[0, 2^n)$ 的范围内枚举一个二进制数 $mask$,其中 $mask$ 的二进制表示是一个 $n$ 位的位串,如果 $mask$ 的第 $i$ 位为 $1$,表示选择 $nums[i]$,为 $0$ 表示不选择 $nums[i]$。注意,如果 $mask$ 的 $i - 1$ 位为 $0$,且 $nums[i] = nums[i - 1]$,则说明在当前枚举到的方案中,第 $i$ 个元素和第 $i - 1$ 个元素相同,为了避免重复,我们跳过这种情况。否则,我们将 $mask$ 对应的子集加入答案数组中。 + +枚举结束后,我们返回答案数组即可。 + +时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + ### **Python3** @@ -52,18 +76,41 @@ ```python class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: - def dfs(u, t): - ans.append(t[:]) - for i in range(u, len(nums)): - if i != u and nums[i] == nums[i - 1]: - continue - t.append(nums[i]) - dfs(i + 1, t) - t.pop() + def dfs(i: int): + if i == len(nums): + ans.append(t[:]) + return + t.append(nums[i]) + dfs(i + 1) + x = t.pop() + while i + 1 < len(nums) and nums[i + 1] == x: + i += 1 + dfs(i + 1) + nums.sort() ans = [] + t = [] + dfs(0) + return ans +``` + +```python +class Solution: + def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.sort() - dfs(0, []) + n = len(nums) + ans = [] + for mask in range(1 << n): + ok = True + t = [] + for i in range(n): + if mask >> i & 1: + if i and (mask >> (i - 1) & 1) == 0 and nums[i] == nums[i - 1]: + ok = False + break + t.append(nums[i]) + if ok: + ans.append(t) return ans ``` @@ -73,27 +120,56 @@ class Solution: ```java class Solution { - private List> ans; + private List> ans = new ArrayList<>(); + private List t = new ArrayList<>(); private int[] nums; public List> subsetsWithDup(int[] nums) { - ans = new ArrayList<>(); Arrays.sort(nums); this.nums = nums; - dfs(0, new ArrayList<>()); + dfs(0); return ans; } - private void dfs(int u, List t) { - ans.add(new ArrayList<>(t)); - for (int i = u; i < nums.length; ++i) { - if (i != u && nums[i] == nums[i - 1]) { - continue; + private void dfs(int i) { + if (i >= nums.length) { + ans.add(new ArrayList<>(t)); + return; + } + t.add(nums[i]); + dfs(i + 1); + int x = t.remove(t.size() - 1); + while (i + 1 < nums.length && nums[i + 1] == x) { + ++i; + } + dfs(i + 1); + } +} +``` + +```java +class Solution { + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + List> ans = new ArrayList<>(); + for (int mask = 0; mask < 1 << n; ++mask) { + List t = new ArrayList<>(); + boolean ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.add(nums[i]); + } + } + if (ok) { + ans.add(t); } - t.add(nums[i]); - dfs(i + 1, t); - t.remove(t.size() - 1); } + return ans; } } ``` @@ -107,18 +183,50 @@ public: sort(nums.begin(), nums.end()); vector> ans; vector t; - dfs(0, t, nums, ans); + int n = nums.size(); + function dfs = [&](int i) { + if (i >= n) { + ans.push_back(t); + return; + } + t.push_back(nums[i]); + dfs(i + 1); + t.pop_back(); + while (i + 1 < n && nums[i + 1] == nums[i]) { + ++i; + } + dfs(i + 1); + }; + dfs(0); return ans; } +}; +``` - void dfs(int u, vector& t, vector& nums, vector>& ans) { - ans.push_back(t); - for (int i = u; i < nums.size(); ++i) { - if (i != u && nums[i] == nums[i - 1]) continue; - t.push_back(nums[i]); - dfs(i + 1, t, nums, ans); - t.pop_back(); +```cpp +class Solution { +public: + vector> subsetsWithDup(vector& nums) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector> ans; + for (int mask = 0; mask < 1 << n; ++mask) { + vector t; + bool ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.push_back(nums[i]); + } + } + if (ok) { + ans.push_back(t); + } } + return ans; } }; ``` @@ -126,24 +234,50 @@ public: ### **Go** ```go -func subsetsWithDup(nums []int) [][]int { +func subsetsWithDup(nums []int) (ans [][]int) { sort.Ints(nums) - var ans [][]int - var dfs func(u int, t []int) - dfs = func(u int, t []int) { - ans = append(ans, append([]int(nil), t...)) - for i := u; i < len(nums); i++ { - if i != u && nums[i] == nums[i-1] { - continue + n := len(nums) + t := []int{} + var dfs func(int) + dfs = func(i int) { + if i >= n { + ans = append(ans, slices.Clone(t)) + return + } + t = append(t, nums[i]) + dfs(i + 1) + t = t[:len(t)-1] + for i+1 < n && nums[i+1] == nums[i] { + i++ + } + dfs(i + 1) + } + dfs(0) + return +} +``` + +```go +func subsetsWithDup(nums []int) (ans [][]int) { + sort.Ints(nums) + n := len(nums) + for mask := 0; mask < 1<>i&1 == 1 { + if i > 0 && mask>>(i-1)&1 == 0 && nums[i] == nums[i-1] { + ok = false + break + } + t = append(t, nums[i]) } - t = append(t, nums[i]) - dfs(i+1, t) - t = t[:len(t)-1] + } + if ok { + ans = append(ans, t) } } - var t []int - dfs(0, t) - return ans + return } ``` @@ -154,22 +288,47 @@ function subsetsWithDup(nums: number[]): number[][] { nums.sort((a, b) => a - b); const n = nums.length; const t: number[] = []; - const res: number[][] = []; - const dfs = (i: number) => { - if (i === n) { - res.push([...t]); + const ans: number[][] = []; + const dfs = (i: number): void => { + if (i >= n) { + ans.push([...t]); return; } t.push(nums[i]); dfs(i + 1); - const num = t.pop(); - while (i < n && nums[i] == num) { + t.pop(); + while (i + 1 < n && nums[i] === nums[i + 1]) { i++; } - dfs(i); + dfs(i + 1); }; dfs(0); - return res; + return ans; +} +``` + +```ts +function subsetsWithDup(nums: number[]): number[][] { + nums.sort((a, b) => a - b); + const n = nums.length; + const ans: number[][] = []; + for (let mask = 0; mask < 1 << n; ++mask) { + const t: number[] = []; + let ok: boolean = true; + for (let i = 0; i < n; ++i) { + if (((mask >> i) & 1) === 1) { + if (i && ((mask >> (i - 1)) & 1) === 0 && nums[i] === nums[i - 1]) { + ok = false; + break; + } + t.push(nums[i]); + } + } + if (ok) { + ans.push(t); + } + } + return ans; } ``` @@ -177,26 +336,57 @@ function subsetsWithDup(nums: number[]): number[][] { ```rust impl Solution { - fn dfs(mut i: usize, t: &mut Vec, res: &mut Vec>, nums: &Vec) { - let n = nums.len(); - if i == n { - res.push(t.clone()); - return; - } - t.push(nums[i]); - Self::dfs(i + 1, t, res, nums); - let num = t.pop().unwrap(); - while i < n && num == nums[i] { - i += 1; + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; + nums.sort(); + let mut ans = Vec::new(); + let mut t = Vec::new(); + + fn dfs(i: usize, nums: &Vec, t: &mut Vec, ans: &mut Vec>) { + if i >= nums.len() { + ans.push(t.clone()); + return; + } + t.push(nums[i]); + dfs(i + 1, nums, t, ans); + t.pop(); + let mut i = i; + while i + 1 < nums.len() && nums[i + 1] == nums[i] { + i += 1; + } + dfs(i + 1, nums, t, ans); } - Self::dfs(i, t, res, nums); + + dfs(0, &nums, &mut t, &mut ans); + ans } +} +``` - pub fn subsets_with_dup(mut nums: Vec) -> Vec> { +```rust +impl Solution { + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; nums.sort(); - let mut res = Vec::new(); - Self::dfs(0, &mut Vec::new(), &mut res, &nums); - res + let n = nums.len(); + let mut ans = Vec::new(); + for mask in 0..1 << n { + let mut t = Vec::new(); + let mut ok = true; + for i in 0..n { + if ((mask >> i) & 1) == 1 { + if i > 0 && ((mask >> (i - 1)) & 1) == 0 && nums[i] == nums[i - 1] { + ok = false; + break; + } + t.push(nums[i]); + } + } + if ok { + ans.push(t); + } + } + ans } } ``` diff --git a/solution/0000-0099/0090.Subsets II/README_EN.md b/solution/0000-0099/0090.Subsets II/README_EN.md index dfd653c7b3114..fcf2dbcd52cc9 100644 --- a/solution/0000-0099/0090.Subsets II/README_EN.md +++ b/solution/0000-0099/0090.Subsets II/README_EN.md @@ -26,6 +26,30 @@ ## Solutions +**Solution 1: Sorting + DFS** + +We can first sort the array $nums$ to facilitate deduplication. + +Then, we design a function $dfs(i)$, which represents searching for subsets starting from the $i$-th element. The execution logic of the function $dfs(i)$ is as follows: + +If $i \geq n$, it means that all elements have been searched, and the current subset is added to the answer array, and the recursion ends. + +If $i < n$, add the $i$-th element to the subset, execute $dfs(i + 1)$, and then remove the $i$-th element from the subset. Next, we judge whether the $i$-th element is the same as the next element. If it is the same, we loop to skip this element until we find the first element that is different from the $i$-th element, and execute $dfs(i + 1)$. + +Finally, we only need to call $dfs(0)$ and return the answer array. + +The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + +**Solution 2: Sorting + Binary Enumeration** + +Similar to Solution 1, we first sort the array $nums$ to facilitate deduplication. + +Next, we enumerate a binary number $mask$ in the range of $[0, 2^n)$, where the binary representation of $mask$ is an $n$-bit bit string. If the $i$-th bit of $mask$ is $1$, it means to select $nums[i]$, and $0$ means not to select $nums[i]$. Note that if the $i - 1$ bit of $mask$ is $0$, and $nums[i] = nums[i - 1]$, it means that in the current enumerated scheme, the $i$-th element and the $i - 1$-th element are the same. To avoid repetition, we skip this situation. Otherwise, we add the subset corresponding to $mask$ to the answer array. + +After the enumeration ends, we return the answer array. + +The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. + ### **Python3** @@ -33,18 +57,41 @@ ```python class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: - def dfs(u, t): - ans.append(t[:]) - for i in range(u, len(nums)): - if i != u and nums[i] == nums[i - 1]: - continue - t.append(nums[i]) - dfs(i + 1, t) - t.pop() + def dfs(i: int): + if i == len(nums): + ans.append(t[:]) + return + t.append(nums[i]) + dfs(i + 1) + x = t.pop() + while i + 1 < len(nums) and nums[i + 1] == x: + i += 1 + dfs(i + 1) + nums.sort() ans = [] + t = [] + dfs(0) + return ans +``` + +```python +class Solution: + def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.sort() - dfs(0, []) + n = len(nums) + ans = [] + for mask in range(1 << n): + ok = True + t = [] + for i in range(n): + if mask >> i & 1: + if i and (mask >> (i - 1) & 1) == 0 and nums[i] == nums[i - 1]: + ok = False + break + t.append(nums[i]) + if ok: + ans.append(t) return ans ``` @@ -52,27 +99,56 @@ class Solution: ```java class Solution { - private List> ans; + private List> ans = new ArrayList<>(); + private List t = new ArrayList<>(); private int[] nums; public List> subsetsWithDup(int[] nums) { - ans = new ArrayList<>(); Arrays.sort(nums); this.nums = nums; - dfs(0, new ArrayList<>()); + dfs(0); return ans; } - private void dfs(int u, List t) { - ans.add(new ArrayList<>(t)); - for (int i = u; i < nums.length; ++i) { - if (i != u && nums[i] == nums[i - 1]) { - continue; + private void dfs(int i) { + if (i >= nums.length) { + ans.add(new ArrayList<>(t)); + return; + } + t.add(nums[i]); + dfs(i + 1); + int x = t.remove(t.size() - 1); + while (i + 1 < nums.length && nums[i + 1] == x) { + ++i; + } + dfs(i + 1); + } +} +``` + +```java +class Solution { + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + List> ans = new ArrayList<>(); + for (int mask = 0; mask < 1 << n; ++mask) { + List t = new ArrayList<>(); + boolean ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.add(nums[i]); + } + } + if (ok) { + ans.add(t); } - t.add(nums[i]); - dfs(i + 1, t); - t.remove(t.size() - 1); } + return ans; } } ``` @@ -86,18 +162,50 @@ public: sort(nums.begin(), nums.end()); vector> ans; vector t; - dfs(0, t, nums, ans); + int n = nums.size(); + function dfs = [&](int i) { + if (i >= n) { + ans.push_back(t); + return; + } + t.push_back(nums[i]); + dfs(i + 1); + t.pop_back(); + while (i + 1 < n && nums[i + 1] == nums[i]) { + ++i; + } + dfs(i + 1); + }; + dfs(0); return ans; } +}; +``` - void dfs(int u, vector& t, vector& nums, vector>& ans) { - ans.push_back(t); - for (int i = u; i < nums.size(); ++i) { - if (i != u && nums[i] == nums[i - 1]) continue; - t.push_back(nums[i]); - dfs(i + 1, t, nums, ans); - t.pop_back(); +```cpp +class Solution { +public: + vector> subsetsWithDup(vector& nums) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector> ans; + for (int mask = 0; mask < 1 << n; ++mask) { + vector t; + bool ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.push_back(nums[i]); + } + } + if (ok) { + ans.push_back(t); + } } + return ans; } }; ``` @@ -105,24 +213,50 @@ public: ### **Go** ```go -func subsetsWithDup(nums []int) [][]int { +func subsetsWithDup(nums []int) (ans [][]int) { sort.Ints(nums) - var ans [][]int - var dfs func(u int, t []int) - dfs = func(u int, t []int) { - ans = append(ans, append([]int(nil), t...)) - for i := u; i < len(nums); i++ { - if i != u && nums[i] == nums[i-1] { - continue + n := len(nums) + t := []int{} + var dfs func(int) + dfs = func(i int) { + if i >= n { + ans = append(ans, slices.Clone(t)) + return + } + t = append(t, nums[i]) + dfs(i + 1) + t = t[:len(t)-1] + for i+1 < n && nums[i+1] == nums[i] { + i++ + } + dfs(i + 1) + } + dfs(0) + return +} +``` + +```go +func subsetsWithDup(nums []int) (ans [][]int) { + sort.Ints(nums) + n := len(nums) + for mask := 0; mask < 1<>i&1 == 1 { + if i > 0 && mask>>(i-1)&1 == 0 && nums[i] == nums[i-1] { + ok = false + break + } + t = append(t, nums[i]) } - t = append(t, nums[i]) - dfs(i+1, t) - t = t[:len(t)-1] + } + if ok { + ans = append(ans, t) } } - var t []int - dfs(0, t) - return ans + return } ``` @@ -133,22 +267,47 @@ function subsetsWithDup(nums: number[]): number[][] { nums.sort((a, b) => a - b); const n = nums.length; const t: number[] = []; - const res: number[][] = []; - const dfs = (i: number) => { - if (i === n) { - res.push([...t]); + const ans: number[][] = []; + const dfs = (i: number): void => { + if (i >= n) { + ans.push([...t]); return; } t.push(nums[i]); dfs(i + 1); - const num = t.pop(); - while (i < n && nums[i] == num) { + t.pop(); + while (i + 1 < n && nums[i] === nums[i + 1]) { i++; } - dfs(i); + dfs(i + 1); }; dfs(0); - return res; + return ans; +} +``` + +```ts +function subsetsWithDup(nums: number[]): number[][] { + nums.sort((a, b) => a - b); + const n = nums.length; + const ans: number[][] = []; + for (let mask = 0; mask < 1 << n; ++mask) { + const t: number[] = []; + let ok: boolean = true; + for (let i = 0; i < n; ++i) { + if (((mask >> i) & 1) === 1) { + if (i && ((mask >> (i - 1)) & 1) === 0 && nums[i] === nums[i - 1]) { + ok = false; + break; + } + t.push(nums[i]); + } + } + if (ok) { + ans.push(t); + } + } + return ans; } ``` @@ -156,26 +315,57 @@ function subsetsWithDup(nums: number[]): number[][] { ```rust impl Solution { - fn dfs(mut i: usize, t: &mut Vec, res: &mut Vec>, nums: &Vec) { - let n = nums.len(); - if i == n { - res.push(t.clone()); - return; - } - t.push(nums[i]); - Self::dfs(i + 1, t, res, nums); - let num = t.pop().unwrap(); - while i < n && num == nums[i] { - i += 1; + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; + nums.sort(); + let mut ans = Vec::new(); + let mut t = Vec::new(); + + fn dfs(i: usize, nums: &Vec, t: &mut Vec, ans: &mut Vec>) { + if i >= nums.len() { + ans.push(t.clone()); + return; + } + t.push(nums[i]); + dfs(i + 1, nums, t, ans); + t.pop(); + let mut i = i; + while i + 1 < nums.len() && nums[i + 1] == nums[i] { + i += 1; + } + dfs(i + 1, nums, t, ans); } - Self::dfs(i, t, res, nums); + + dfs(0, &nums, &mut t, &mut ans); + ans } +} +``` - pub fn subsets_with_dup(mut nums: Vec) -> Vec> { +```rust +impl Solution { + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; nums.sort(); - let mut res = Vec::new(); - Self::dfs(0, &mut Vec::new(), &mut res, &nums); - res + let n = nums.len(); + let mut ans = Vec::new(); + for mask in 0..1 << n { + let mut t = Vec::new(); + let mut ok = true; + for i in 0..n { + if ((mask >> i) & 1) == 1 { + if i > 0 && ((mask >> (i - 1)) & 1) == 0 && nums[i] == nums[i - 1] { + ok = false; + break; + } + t.push(nums[i]); + } + } + if ok { + ans.push(t); + } + } + ans } } ``` diff --git a/solution/0000-0099/0090.Subsets II/Solution.cpp b/solution/0000-0099/0090.Subsets II/Solution.cpp index 0e6912965a5ff..58c1ad52fb29a 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.cpp +++ b/solution/0000-0099/0090.Subsets II/Solution.cpp @@ -1,20 +1,25 @@ -class Solution { -public: - vector> subsetsWithDup(vector& nums) { - sort(nums.begin(), nums.end()); - vector> ans; - vector t; - dfs(0, t, nums, ans); - return ans; - } - - void dfs(int u, vector& t, vector& nums, vector>& ans) { - ans.push_back(t); - for (int i = u; i < nums.size(); ++i) { - if (i != u && nums[i] == nums[i - 1]) continue; - t.push_back(nums[i]); - dfs(i + 1, t, nums, ans); - t.pop_back(); - } - } +class Solution { +public: + vector> subsetsWithDup(vector& nums) { + sort(nums.begin(), nums.end()); + int n = nums.size(); + vector> ans; + for (int mask = 0; mask < 1 << n; ++mask) { + vector t; + bool ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.push_back(nums[i]); + } + } + if (ok) { + ans.push_back(t); + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/0000-0099/0090.Subsets II/Solution.go b/solution/0000-0099/0090.Subsets II/Solution.go index 003cdcd8b87ca..cec1dc4a9d090 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.go +++ b/solution/0000-0099/0090.Subsets II/Solution.go @@ -1,19 +1,21 @@ -func subsetsWithDup(nums []int) [][]int { +func subsetsWithDup(nums []int) (ans [][]int) { sort.Ints(nums) - var ans [][]int - var dfs func(u int, t []int) - dfs = func(u int, t []int) { - ans = append(ans, append([]int(nil), t...)) - for i := u; i < len(nums); i++ { - if i != u && nums[i] == nums[i-1] { - continue + n := len(nums) + for mask := 0; mask < 1<>i&1 == 1 { + if i > 0 && mask>>(i-1)&1 == 0 && nums[i] == nums[i-1] { + ok = false + break + } + t = append(t, nums[i]) } - t = append(t, nums[i]) - dfs(i+1, t) - t = t[:len(t)-1] + } + if ok { + ans = append(ans, t) } } - var t []int - dfs(0, t) - return ans + return } \ No newline at end of file diff --git a/solution/0000-0099/0090.Subsets II/Solution.java b/solution/0000-0099/0090.Subsets II/Solution.java index 3dabfa9029db1..53c9c7d4c7194 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.java +++ b/solution/0000-0099/0090.Subsets II/Solution.java @@ -1,24 +1,24 @@ -class Solution { - private List> ans; - private int[] nums; - - public List> subsetsWithDup(int[] nums) { - ans = new ArrayList<>(); - Arrays.sort(nums); - this.nums = nums; - dfs(0, new ArrayList<>()); - return ans; - } - - private void dfs(int u, List t) { - ans.add(new ArrayList<>(t)); - for (int i = u; i < nums.length; ++i) { - if (i != u && nums[i] == nums[i - 1]) { - continue; - } - t.add(nums[i]); - dfs(i + 1, t); - t.remove(t.size() - 1); - } - } +class Solution { + public List> subsetsWithDup(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + List> ans = new ArrayList<>(); + for (int mask = 0; mask < 1 << n; ++mask) { + List t = new ArrayList<>(); + boolean ok = true; + for (int i = 0; i < n; ++i) { + if ((mask >> i & 1) == 1) { + if (i > 0 && (mask >> (i - 1) & 1) == 0 && nums[i] == nums[i - 1]) { + ok = false; + break; + } + t.add(nums[i]); + } + } + if (ok) { + ans.add(t); + } + } + return ans; + } } \ No newline at end of file diff --git a/solution/0000-0099/0090.Subsets II/Solution.py b/solution/0000-0099/0090.Subsets II/Solution.py index d15f8a7584fd4..c0aa8d12289f2 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.py +++ b/solution/0000-0099/0090.Subsets II/Solution.py @@ -1,15 +1,17 @@ -class Solution: - def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: - def dfs(u, t): - ans.append(t[:]) - for i in range(u, len(nums)): - if i != u and nums[i] == nums[i - 1]: - continue - t.append(nums[i]) - dfs(i + 1, t) - t.pop() - - ans = [] - nums.sort() - dfs(0, []) - return ans +class Solution: + def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: + nums.sort() + n = len(nums) + ans = [] + for mask in range(1 << n): + ok = True + t = [] + for i in range(n): + if mask >> i & 1: + if i and (mask >> (i - 1) & 1) == 0 and nums[i] == nums[i - 1]: + ok = False + break + t.append(nums[i]) + if ok: + ans.append(t) + return ans diff --git a/solution/0000-0099/0090.Subsets II/Solution.rs b/solution/0000-0099/0090.Subsets II/Solution.rs index 7f3534e995464..6f272559d3d46 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.rs +++ b/solution/0000-0099/0090.Subsets II/Solution.rs @@ -1,23 +1,25 @@ impl Solution { - fn dfs(mut i: usize, t: &mut Vec, res: &mut Vec>, nums: &Vec) { + pub fn subsets_with_dup(nums: Vec) -> Vec> { + let mut nums = nums; + nums.sort(); let n = nums.len(); - if i == n { - res.push(t.clone()); - return; - } - t.push(nums[i]); - Self::dfs(i + 1, t, res, nums); - let num = t.pop().unwrap(); - while i < n && num == nums[i] { - i += 1; + let mut ans = Vec::new(); + for mask in 0..1 << n { + let mut t = Vec::new(); + let mut ok = true; + for i in 0..n { + if ((mask >> i) & 1) == 1 { + if i > 0 && ((mask >> (i - 1)) & 1) == 0 && nums[i] == nums[i - 1] { + ok = false; + break; + } + t.push(nums[i]); + } + } + if ok { + ans.push(t); + } } - Self::dfs(i, t, res, nums); - } - - pub fn subsets_with_dup(mut nums: Vec) -> Vec> { - nums.sort(); - let mut res = Vec::new(); - Self::dfs(0, &mut Vec::new(), &mut res, &nums); - res + ans } } diff --git a/solution/0000-0099/0090.Subsets II/Solution.ts b/solution/0000-0099/0090.Subsets II/Solution.ts index 640eb0f062c2c..9ac9ba3681a87 100644 --- a/solution/0000-0099/0090.Subsets II/Solution.ts +++ b/solution/0000-0099/0090.Subsets II/Solution.ts @@ -1,21 +1,22 @@ function subsetsWithDup(nums: number[]): number[][] { nums.sort((a, b) => a - b); const n = nums.length; - const t: number[] = []; - const res: number[][] = []; - const dfs = (i: number) => { - if (i === n) { - res.push([...t]); - return; + const ans: number[][] = []; + for (let mask = 0; mask < 1 << n; ++mask) { + const t: number[] = []; + let ok: boolean = true; + for (let i = 0; i < n; ++i) { + if (((mask >> i) & 1) === 1) { + if (i && ((mask >> (i - 1)) & 1) === 0 && nums[i] === nums[i - 1]) { + ok = false; + break; + } + t.push(nums[i]); + } } - t.push(nums[i]); - dfs(i + 1); - const num = t.pop(); - while (i < n && nums[i] == num) { - i++; + if (ok) { + ans.push(t); } - dfs(i); - }; - dfs(0); - return res; + } + return ans; }