Skip to content

Commit a7e034d

Browse files
authored
feat: update solutions to lc problem: No.2007 (#2595)
No.2007.Find Original Array From Doubled Array
1 parent 94405ad commit a7e034d

File tree

7 files changed

+115
-173
lines changed

7 files changed

+115
-173
lines changed

solution/2000-2099/2007.Find Original Array From Doubled Array/README.md

+40-60
Original file line numberDiff line numberDiff line change
@@ -50,66 +50,59 @@
5050

5151
## 解法
5252

53-
### 方法一:排序 + 计数 + 遍历
53+
### 方法一:排序
5454

55-
我们先判断数组 `changed` 的长度 $n$ 是否为奇数,若是,则直接返回空数组
55+
我们注意到,如果数组 `changed` 是一个双倍数组,那么数组 `changed` 中最小的元素也一定是原数组中的元素,因此,我们可以先对数组 `changed` 进行排序,然后以第一个元素作为起点,从小到大遍历数组 `changed`
5656

57-
然后对数组 `changed` 进行排序,并且用哈希表或数组 `cnt` 统计数组 `changed` 中每个元素出现的次数
57+
我们使用一个哈希表或数组 $cnt$ 来统计数组 `changed` 中每个元素的出现次数。对于数组 `changed` 中的每个元素 $x$,我们首先检查 $x$ 是否存在于 $cnt$ 中。如果不存在,我们直接跳过这个元素。否则,我们将 $cnt[x]$ 减一,并检查 $x \times 2$ 是否存在于 $cnt$ 中。如果不存在,我们直接返回一个空数组。否则,我们将 $cnt[x \times 2]$ 减一,并将 $x$ 加入答案数组中
5858

59-
接下来遍历数组 `changed`,对于数组 `changed` 中的每个元素 $x$,我们首先判断哈希表 `cnt` 中是否存在 $x$,若不存在,则直接跳过该元素。否则,我们判断 `cnt` 中是否存在 $x \times 2$,若不存在,则直接返回空数组。否则,我们将 $x$ 加入答案数组 `ans` 中,并且将 `cnt` 中 $x$ 和 $x \times 2$ 的出现次数分别减 $1$
59+
遍历结束后,返回答案数组即可
6060

61-
遍历结束后,我们判断答案数组 `ans` 的长度是否为 $\frac{n}{2}$,若是,则返回 `ans`,否则返回空数组。
62-
63-
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `changed` 的长度。
61+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$,其中 $n$ 为数组 `changed` 的长度。
6462

6563
<!-- tabs:start -->
6664

6765
```python
6866
class Solution:
6967
def findOriginalArray(self, changed: List[int]) -> List[int]:
70-
n = len(changed)
71-
if n & 1:
72-
return []
73-
cnt = Counter(changed)
7468
changed.sort()
69+
cnt = Counter(changed)
7570
ans = []
7671
for x in changed:
7772
if cnt[x] == 0:
7873
continue
79-
if cnt[x * 2] <= 0:
74+
cnt[x] -= 1
75+
if cnt[x << 1] <= 0:
8076
return []
77+
cnt[x << 1] -= 1
8178
ans.append(x)
82-
cnt[x] -= 1
83-
cnt[x * 2] -= 1
84-
return ans if len(ans) == n // 2 else []
79+
return ans
8580
```
8681

8782
```java
8883
class Solution {
8984
public int[] findOriginalArray(int[] changed) {
9085
int n = changed.length;
91-
if (n % 2 == 1) {
92-
return new int[] {};
93-
}
9486
Arrays.sort(changed);
9587
int[] cnt = new int[changed[n - 1] + 1];
9688
for (int x : changed) {
9789
++cnt[x];
9890
}
99-
int[] ans = new int[n / 2];
91+
int[] ans = new int[n >> 1];
10092
int i = 0;
10193
for (int x : changed) {
10294
if (cnt[x] == 0) {
10395
continue;
10496
}
105-
if (x * 2 >= cnt.length || cnt[x * 2] <= 0) {
106-
return new int[] {};
97+
--cnt[x];
98+
int y = x << 1;
99+
if (y >= cnt.length || cnt[y] <= 0) {
100+
return new int[0];
107101
}
102+
--cnt[y];
108103
ans[i++] = x;
109-
cnt[x]--;
110-
cnt[x * 2]--;
111104
}
112-
return i == n / 2 ? ans : new int[] {};
105+
return ans;
113106
}
114107
}
115108
```
@@ -118,86 +111,73 @@ class Solution {
118111
class Solution {
119112
public:
120113
vector<int> findOriginalArray(vector<int>& changed) {
121-
int n = changed.size();
122-
if (n & 1) {
123-
return {};
124-
}
125114
sort(changed.begin(), changed.end());
126115
vector<int> cnt(changed.back() + 1);
127-
for (int& x : changed) {
116+
for (int x : changed) {
128117
++cnt[x];
129118
}
130119
vector<int> ans;
131-
for (int& x : changed) {
120+
for (int x : changed) {
132121
if (cnt[x] == 0) {
133122
continue;
134123
}
135-
if (x * 2 >= cnt.size() || cnt[x * 2] <= 0) {
124+
--cnt[x];
125+
int y = x << 1;
126+
if (y >= cnt.size() || cnt[y] <= 0) {
136127
return {};
137128
}
129+
--cnt[y];
138130
ans.push_back(x);
139-
--cnt[x];
140-
--cnt[x * 2];
141131
}
142-
return ans.size() == n / 2 ? ans : vector<int>();
132+
return ans;
143133
}
144134
};
145135
```
146136
147137
```go
148-
func findOriginalArray(changed []int) []int {
149-
n := len(changed)
150-
ans := []int{}
151-
if n&1 == 1 {
152-
return ans
153-
}
138+
func findOriginalArray(changed []int) (ans []int) {
154139
sort.Ints(changed)
155-
cnt := make([]int, changed[n-1]+1)
140+
cnt := make([]int, changed[len(changed)-1]+1)
156141
for _, x := range changed {
157142
cnt[x]++
158143
}
159144
for _, x := range changed {
160145
if cnt[x] == 0 {
161146
continue
162147
}
163-
if x*2 >= len(cnt) || cnt[x*2] <= 0 {
148+
cnt[x]--
149+
y := x << 1
150+
if y >= len(cnt) || cnt[y] <= 0 {
164151
return []int{}
165152
}
153+
cnt[y]--
166154
ans = append(ans, x)
167-
cnt[x]--
168-
cnt[x*2]--
169155
}
170-
if len(ans) != n/2 {
171-
return []int{}
172-
}
173-
return ans
156+
return
174157
}
175158
```
176159

177160
```ts
178161
function findOriginalArray(changed: number[]): number[] {
179-
const n = changed.length;
180-
if (n & 1) {
181-
return [];
182-
}
183-
const cnt = new Map<number, number>();
162+
changed.sort((a, b) => a - b);
163+
const cnt: number[] = Array(changed.at(-1)! + 1).fill(0);
184164
for (const x of changed) {
185-
cnt.set(x, (cnt.get(x) || 0) + 1);
165+
++cnt[x];
186166
}
187-
changed.sort((a, b) => a - b);
188167
const ans: number[] = [];
189168
for (const x of changed) {
190-
if (cnt.get(x) == 0) {
169+
if (cnt[x] === 0) {
191170
continue;
192171
}
193-
if ((cnt.get(x * 2) || 0) <= 0) {
172+
cnt[x]--;
173+
const y = x << 1;
174+
if (y >= cnt.length || cnt[y] <= 0) {
194175
return [];
195176
}
177+
cnt[y]--;
196178
ans.push(x);
197-
cnt.set(x, (cnt.get(x) || 0) - 1);
198-
cnt.set(x * 2, (cnt.get(x * 2) || 0) - 1);
199179
}
200-
return ans.length == n / 2 ? ans : [];
180+
return ans;
201181
}
202182
```
203183

solution/2000-2099/2007.Find Original Array From Doubled Array/README_EN.md

+40-60
Original file line numberDiff line numberDiff line change
@@ -49,66 +49,59 @@ Other original arrays could be [4,3,1] or [3,1,4].
4949

5050
## Solutions
5151

52-
### Solution 1: Sorting + Counting + Traversal
52+
### Solution 1: Sorting
5353

54-
First, we check if the length $n$ of the array `changed` is odd. If it is, we directly return an empty array.
54+
We notice that if the array `changed` is a double array, then the smallest element in the array `changed` must also be an element in the original array. Therefore, we can first sort the array `changed`, and then start from the first element to traverse the array `changed` in ascending order.
5555

56-
Then, we sort the array `changed`, and use a hash table or array `cnt` to count the occurrence of each element in `changed`.
56+
We use a hash table or array $cnt$ to count the occurrence of each element in the array `changed`. For each element $x$ in the array `changed`, we first check whether $x$ exists in $cnt$. If it does not exist, we skip this element. Otherwise, we subtract one from $cnt[x]$, and check whether $x \times 2$ exists in $cnt$. If it does not exist, we return an empty array directly. Otherwise, we subtract one from $cnt[x \times 2]$, and add $x$ to the answer array.
5757

58-
Next, we traverse the array `changed`. For each element $x$ in `changed`, we first check if $x$ exists in the hash table `cnt`. If it does not exist, we directly skip this element. Otherwise, we check if $x \times 2$ exists in `cnt`. If it does not exist, we directly return an empty array. Otherwise, we add $x$ to the answer array `ans`, and decrease the occurrence counts of $x$ and $x \times 2$ in `cnt` by $1$ each.
58+
After the traversal, we return the answer array.
5959

60-
After the traversal, we check if the length of the answer array `ans` is $\frac{n}{2}$. If it is, we return `ans`, otherwise we return an empty array.
61-
62-
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array `changed`.
60+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$, where $n$ is the length of the array `changed`.
6361

6462
<!-- tabs:start -->
6563

6664
```python
6765
class Solution:
6866
def findOriginalArray(self, changed: List[int]) -> List[int]:
69-
n = len(changed)
70-
if n & 1:
71-
return []
72-
cnt = Counter(changed)
7367
changed.sort()
68+
cnt = Counter(changed)
7469
ans = []
7570
for x in changed:
7671
if cnt[x] == 0:
7772
continue
78-
if cnt[x * 2] <= 0:
73+
cnt[x] -= 1
74+
if cnt[x << 1] <= 0:
7975
return []
76+
cnt[x << 1] -= 1
8077
ans.append(x)
81-
cnt[x] -= 1
82-
cnt[x * 2] -= 1
83-
return ans if len(ans) == n // 2 else []
78+
return ans
8479
```
8580

8681
```java
8782
class Solution {
8883
public int[] findOriginalArray(int[] changed) {
8984
int n = changed.length;
90-
if (n % 2 == 1) {
91-
return new int[] {};
92-
}
9385
Arrays.sort(changed);
9486
int[] cnt = new int[changed[n - 1] + 1];
9587
for (int x : changed) {
9688
++cnt[x];
9789
}
98-
int[] ans = new int[n / 2];
90+
int[] ans = new int[n >> 1];
9991
int i = 0;
10092
for (int x : changed) {
10193
if (cnt[x] == 0) {
10294
continue;
10395
}
104-
if (x * 2 >= cnt.length || cnt[x * 2] <= 0) {
105-
return new int[] {};
96+
--cnt[x];
97+
int y = x << 1;
98+
if (y >= cnt.length || cnt[y] <= 0) {
99+
return new int[0];
106100
}
101+
--cnt[y];
107102
ans[i++] = x;
108-
cnt[x]--;
109-
cnt[x * 2]--;
110103
}
111-
return i == n / 2 ? ans : new int[] {};
104+
return ans;
112105
}
113106
}
114107
```
@@ -117,86 +110,73 @@ class Solution {
117110
class Solution {
118111
public:
119112
vector<int> findOriginalArray(vector<int>& changed) {
120-
int n = changed.size();
121-
if (n & 1) {
122-
return {};
123-
}
124113
sort(changed.begin(), changed.end());
125114
vector<int> cnt(changed.back() + 1);
126-
for (int& x : changed) {
115+
for (int x : changed) {
127116
++cnt[x];
128117
}
129118
vector<int> ans;
130-
for (int& x : changed) {
119+
for (int x : changed) {
131120
if (cnt[x] == 0) {
132121
continue;
133122
}
134-
if (x * 2 >= cnt.size() || cnt[x * 2] <= 0) {
123+
--cnt[x];
124+
int y = x << 1;
125+
if (y >= cnt.size() || cnt[y] <= 0) {
135126
return {};
136127
}
128+
--cnt[y];
137129
ans.push_back(x);
138-
--cnt[x];
139-
--cnt[x * 2];
140130
}
141-
return ans.size() == n / 2 ? ans : vector<int>();
131+
return ans;
142132
}
143133
};
144134
```
145135
146136
```go
147-
func findOriginalArray(changed []int) []int {
148-
n := len(changed)
149-
ans := []int{}
150-
if n&1 == 1 {
151-
return ans
152-
}
137+
func findOriginalArray(changed []int) (ans []int) {
153138
sort.Ints(changed)
154-
cnt := make([]int, changed[n-1]+1)
139+
cnt := make([]int, changed[len(changed)-1]+1)
155140
for _, x := range changed {
156141
cnt[x]++
157142
}
158143
for _, x := range changed {
159144
if cnt[x] == 0 {
160145
continue
161146
}
162-
if x*2 >= len(cnt) || cnt[x*2] <= 0 {
147+
cnt[x]--
148+
y := x << 1
149+
if y >= len(cnt) || cnt[y] <= 0 {
163150
return []int{}
164151
}
152+
cnt[y]--
165153
ans = append(ans, x)
166-
cnt[x]--
167-
cnt[x*2]--
168154
}
169-
if len(ans) != n/2 {
170-
return []int{}
171-
}
172-
return ans
155+
return
173156
}
174157
```
175158

176159
```ts
177160
function findOriginalArray(changed: number[]): number[] {
178-
const n = changed.length;
179-
if (n & 1) {
180-
return [];
181-
}
182-
const cnt = new Map<number, number>();
161+
changed.sort((a, b) => a - b);
162+
const cnt: number[] = Array(changed.at(-1)! + 1).fill(0);
183163
for (const x of changed) {
184-
cnt.set(x, (cnt.get(x) || 0) + 1);
164+
++cnt[x];
185165
}
186-
changed.sort((a, b) => a - b);
187166
const ans: number[] = [];
188167
for (const x of changed) {
189-
if (cnt.get(x) == 0) {
168+
if (cnt[x] === 0) {
190169
continue;
191170
}
192-
if ((cnt.get(x * 2) || 0) <= 0) {
171+
cnt[x]--;
172+
const y = x << 1;
173+
if (y >= cnt.length || cnt[y] <= 0) {
193174
return [];
194175
}
176+
cnt[y]--;
195177
ans.push(x);
196-
cnt.set(x, (cnt.get(x) || 0) - 1);
197-
cnt.set(x * 2, (cnt.get(x * 2) || 0) - 1);
198178
}
199-
return ans.length == n / 2 ? ans : [];
179+
return ans;
200180
}
201181
```
202182

0 commit comments

Comments
 (0)