Skip to content

Commit 31fdeb7

Browse files
committed
feat: add solutions to lc problem: No.2007
No.2007.Find Original Array From Doubled Array
1 parent aa1e80b commit 31fdeb7

File tree

7 files changed

+289
-195
lines changed

7 files changed

+289
-195
lines changed

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

Lines changed: 106 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53+
**方法一:排序 + 计数 + 遍历**
54+
55+
我们先判断数组 `changed` 的长度 $n$ 是否为奇数,若是,则直接返回空数组。
56+
57+
然后对数组 `changed` 进行排序,并且用哈希表或数组 `cnt` 统计数组 `changed` 中每个元素出现的次数。
58+
59+
接下来遍历数组 `changed`,对于数组 `changed` 中的每个元素 $x$,我们首先判断哈希表 `cnt` 中是否存在 $x$,若不存在,则直接跳过该元素。否则,我们判断 `cnt` 中是否存在 $x \times 2$,若不存在,则直接返回空数组。否则,我们将 $x$ 加入答案数组 `ans` 中,并且将 `cnt` 中 $x$ 和 $x \times 2$ 的出现次数分别减 $1$。
60+
61+
遍历结束后,我们判断答案数组 `ans` 的长度是否为 $\frac{n}{2}$,若是,则返回 `ans`,否则返回空数组。
62+
63+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `changed` 的长度。
64+
5365
<!-- tabs:start -->
5466

5567
### **Python3**
@@ -59,23 +71,21 @@
5971
```python
6072
class Solution:
6173
def findOriginalArray(self, changed: List[int]) -> List[int]:
62-
if len(changed) % 2 != 0:
74+
n = len(changed)
75+
if n & 1:
6376
return []
64-
n = 100010
65-
counter = [0] * n
77+
cnt = Counter(changed)
78+
changed.sort()
79+
ans = []
6680
for x in changed:
67-
counter[x] += 1
68-
if counter[0] % 2 != 0:
69-
return []
70-
res = [0] * (counter[0] // 2)
71-
for i in range(1, n):
72-
if counter[i] == 0:
81+
if cnt[x] == 0:
7382
continue
74-
if i * 2 > n or counter[i] > counter[i * 2]:
83+
if cnt[x * 2] <= 0:
7584
return []
76-
res.extend([i] * counter[i])
77-
counter[i * 2] -= counter[i]
78-
return res
85+
ans.append(x)
86+
cnt[x] -= 1
87+
cnt[x * 2] -= 1
88+
return ans if len(ans) == n // 2 else []
7989
```
8090

8191
### **Java**
@@ -85,32 +95,29 @@ class Solution:
8595
```java
8696
class Solution {
8797
public int[] findOriginalArray(int[] changed) {
88-
if (changed.length % 2 != 0) {
89-
return new int[] {};
98+
int n = changed.length;
99+
if (n % 2 == 1) {
100+
return new int[]{};
90101
}
91-
int n = 100010;
92-
int[] counter = new int[n];
102+
Arrays.sort(changed);
103+
int[] cnt = new int[changed[n - 1] + 1];
93104
for (int x : changed) {
94-
++counter[x];
95-
}
96-
if (counter[0] % 2 != 0) {
97-
return new int[] {};
105+
++cnt[x];
98106
}
99-
int[] res = new int[changed.length / 2];
100-
int j = counter[0] / 2;
101-
for (int i = 1; i < n; ++i) {
102-
if (counter[i] == 0) {
107+
int[] ans = new int[n / 2];
108+
int i = 0;
109+
for (int x : changed) {
110+
if (cnt[x] == 0) {
103111
continue;
104112
}
105-
if (i * 2 >= n || counter[i] > counter[i * 2]) {
106-
return new int[] {};
107-
}
108-
counter[i * 2] -= counter[i];
109-
while (counter[i]-- > 0) {
110-
res[j++] = i;
113+
if (x * 2 >= cnt.length || cnt[x * 2] <= 0) {
114+
return new int[]{};
111115
}
116+
ans[i++] = x;
117+
cnt[x]--;
118+
cnt[x * 2]--;
112119
}
113-
return res;
120+
return i == n / 2 ? ans : new int[]{};
114121
}
115122
}
116123
```
@@ -121,20 +128,28 @@ class Solution {
121128
class Solution {
122129
public:
123130
vector<int> findOriginalArray(vector<int>& changed) {
124-
if (changed.size() % 2 != 0) return {};
125-
int n = 100010;
126-
vector<int> counter(n);
127-
for (int x : changed) ++counter[x];
128-
if (counter[0] % 2 != 0) return {};
129-
vector<int> res(changed.size() / 2);
130-
int j = counter[0] / 2;
131-
for (int i = 1; i < n; ++i) {
132-
if (counter[i] == 0) continue;
133-
if (i * 2 >= n || counter[i] > counter[i * 2]) return {};
134-
counter[i * 2] -= counter[i];
135-
while (counter[i]--) res[j++] = i;
131+
int n = changed.size();
132+
if (n & 1) {
133+
return {};
134+
}
135+
sort(changed.begin(), changed.end());
136+
vector<int> cnt(changed.back() + 1);
137+
for (int& x : changed) {
138+
++cnt[x];
139+
}
140+
vector<int> ans;
141+
for (int& x : changed) {
142+
if (cnt[x] == 0) {
143+
continue;
144+
}
145+
if (x * 2 >= cnt.size() || cnt[x * 2] <= 0) {
146+
return {};
147+
}
148+
ans.push_back(x);
149+
--cnt[x];
150+
--cnt[x * 2];
136151
}
137-
return res;
152+
return ans.size() == n / 2 ? ans : vector<int>();
138153
}
139154
};
140155
```
@@ -143,34 +158,60 @@ public:
143158
144159
```go
145160
func findOriginalArray(changed []int) []int {
146-
if len(changed)%2 != 0 {
147-
return []int{}
161+
n := len(changed)
162+
ans := []int{}
163+
if n&1 == 1 {
164+
return ans
148165
}
149-
n := 100010
150-
counter := make([]int, n)
166+
sort.Ints(changed)
167+
cnt := make([]int, changed[n-1]+1)
151168
for _, x := range changed {
152-
counter[x]++
169+
cnt[x]++
153170
}
154-
if counter[0]%2 != 0 {
155-
return []int{}
156-
}
157-
var res []int
158-
for j := 0; j < counter[0]/2; j++ {
159-
res = append(res, 0)
160-
}
161-
for i := 1; i < n; i++ {
162-
if counter[i] == 0 {
171+
for _, x := range changed {
172+
if cnt[x] == 0 {
163173
continue
164174
}
165-
if i*2 >= n || counter[i] > counter[i*2] {
175+
if x*2 >= len(cnt) || cnt[x*2] <= 0 {
166176
return []int{}
167177
}
168-
for j := 0; j < counter[i]; j++ {
169-
res = append(res, i)
170-
}
171-
counter[i*2] -= counter[i]
178+
ans = append(ans, x)
179+
cnt[x]--
180+
cnt[x*2]--
181+
}
182+
if len(ans) != n/2 {
183+
return []int{}
172184
}
173-
return res
185+
return ans
186+
}
187+
```
188+
189+
### **TypeScript**
190+
191+
```ts
192+
function findOriginalArray(changed: number[]): number[] {
193+
const n = changed.length;
194+
if (n & 1) {
195+
return [];
196+
}
197+
const cnt = new Map<number, number>();
198+
for (const x of changed) {
199+
cnt.set(x, (cnt.get(x) || 0) + 1);
200+
}
201+
changed.sort((a, b) => a - b);
202+
const ans: number[] = [];
203+
for (const x of changed) {
204+
if (cnt.get(x) == 0) {
205+
continue;
206+
}
207+
if ((cnt.get(x * 2) || 0) <= 0) {
208+
return [];
209+
}
210+
ans.push(x);
211+
cnt.set(x, (cnt.get(x) || 0) - 1);
212+
cnt.set(x * 2, (cnt.get(x * 2) || 0) - 1);
213+
}
214+
return ans.length == n / 2 ? ans : [];
174215
}
175216
```
176217

0 commit comments

Comments
 (0)