diff --git a/solution/2000-2099/2007.Find Original Array From Doubled Array/README.md b/solution/2000-2099/2007.Find Original Array From Doubled Array/README.md index 03edb273d0475..81cba374151e9 100644 --- a/solution/2000-2099/2007.Find Original Array From Doubled Array/README.md +++ b/solution/2000-2099/2007.Find Original Array From Doubled Array/README.md @@ -50,66 +50,59 @@ ## 解法 -### 方法一:排序 + 计数 + 遍历 +### 方法一:排序 -我们先判断数组 `changed` 的长度 $n$ 是否为奇数,若是,则直接返回空数组。 +我们注意到,如果数组 `changed` 是一个双倍数组,那么数组 `changed` 中最小的元素也一定是原数组中的元素,因此,我们可以先对数组 `changed` 进行排序,然后以第一个元素作为起点,从小到大遍历数组 `changed`。 -然后对数组 `changed` 进行排序,并且用哈希表或数组 `cnt` 统计数组 `changed` 中每个元素出现的次数。 +我们使用一个哈希表或数组 $cnt$ 来统计数组 `changed` 中每个元素的出现次数。对于数组 `changed` 中的每个元素 $x$,我们首先检查 $x$ 是否存在于 $cnt$ 中。如果不存在,我们直接跳过这个元素。否则,我们将 $cnt[x]$ 减一,并检查 $x \times 2$ 是否存在于 $cnt$ 中。如果不存在,我们直接返回一个空数组。否则,我们将 $cnt[x \times 2]$ 减一,并将 $x$ 加入答案数组中。 -接下来遍历数组 `changed`,对于数组 `changed` 中的每个元素 $x$,我们首先判断哈希表 `cnt` 中是否存在 $x$,若不存在,则直接跳过该元素。否则,我们判断 `cnt` 中是否存在 $x \times 2$,若不存在,则直接返回空数组。否则,我们将 $x$ 加入答案数组 `ans` 中,并且将 `cnt` 中 $x$ 和 $x \times 2$ 的出现次数分别减 $1$。 +遍历结束后,返回答案数组即可。 -遍历结束后,我们判断答案数组 `ans` 的长度是否为 $\frac{n}{2}$,若是,则返回 `ans`,否则返回空数组。 - -时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `changed` 的长度。 +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$,其中 $n$ 为数组 `changed` 的长度。 ```python class Solution: def findOriginalArray(self, changed: List[int]) -> List[int]: - n = len(changed) - if n & 1: - return [] - cnt = Counter(changed) changed.sort() + cnt = Counter(changed) ans = [] for x in changed: if cnt[x] == 0: continue - if cnt[x * 2] <= 0: + cnt[x] -= 1 + if cnt[x << 1] <= 0: return [] + cnt[x << 1] -= 1 ans.append(x) - cnt[x] -= 1 - cnt[x * 2] -= 1 - return ans if len(ans) == n // 2 else [] + return ans ``` ```java class Solution { public int[] findOriginalArray(int[] changed) { int n = changed.length; - if (n % 2 == 1) { - return new int[] {}; - } Arrays.sort(changed); int[] cnt = new int[changed[n - 1] + 1]; for (int x : changed) { ++cnt[x]; } - int[] ans = new int[n / 2]; + int[] ans = new int[n >> 1]; int i = 0; for (int x : changed) { if (cnt[x] == 0) { continue; } - if (x * 2 >= cnt.length || cnt[x * 2] <= 0) { - return new int[] {}; + --cnt[x]; + int y = x << 1; + if (y >= cnt.length || cnt[y] <= 0) { + return new int[0]; } + --cnt[y]; ans[i++] = x; - cnt[x]--; - cnt[x * 2]--; } - return i == n / 2 ? ans : new int[] {}; + return ans; } } ``` @@ -118,41 +111,33 @@ class Solution { class Solution { public: vector findOriginalArray(vector& changed) { - int n = changed.size(); - if (n & 1) { - return {}; - } sort(changed.begin(), changed.end()); vector cnt(changed.back() + 1); - for (int& x : changed) { + for (int x : changed) { ++cnt[x]; } vector ans; - for (int& x : changed) { + for (int x : changed) { if (cnt[x] == 0) { continue; } - if (x * 2 >= cnt.size() || cnt[x * 2] <= 0) { + --cnt[x]; + int y = x << 1; + if (y >= cnt.size() || cnt[y] <= 0) { return {}; } + --cnt[y]; ans.push_back(x); - --cnt[x]; - --cnt[x * 2]; } - return ans.size() == n / 2 ? ans : vector(); + return ans; } }; ``` ```go -func findOriginalArray(changed []int) []int { - n := len(changed) - ans := []int{} - if n&1 == 1 { - return ans - } +func findOriginalArray(changed []int) (ans []int) { sort.Ints(changed) - cnt := make([]int, changed[n-1]+1) + cnt := make([]int, changed[len(changed)-1]+1) for _, x := range changed { cnt[x]++ } @@ -160,44 +145,39 @@ func findOriginalArray(changed []int) []int { if cnt[x] == 0 { continue } - if x*2 >= len(cnt) || cnt[x*2] <= 0 { + cnt[x]-- + y := x << 1 + if y >= len(cnt) || cnt[y] <= 0 { return []int{} } + cnt[y]-- ans = append(ans, x) - cnt[x]-- - cnt[x*2]-- } - if len(ans) != n/2 { - return []int{} - } - return ans + return } ``` ```ts function findOriginalArray(changed: number[]): number[] { - const n = changed.length; - if (n & 1) { - return []; - } - const cnt = new Map(); + changed.sort((a, b) => a - b); + const cnt: number[] = Array(changed.at(-1)! + 1).fill(0); for (const x of changed) { - cnt.set(x, (cnt.get(x) || 0) + 1); + ++cnt[x]; } - changed.sort((a, b) => a - b); const ans: number[] = []; for (const x of changed) { - if (cnt.get(x) == 0) { + if (cnt[x] === 0) { continue; } - if ((cnt.get(x * 2) || 0) <= 0) { + cnt[x]--; + const y = x << 1; + if (y >= cnt.length || cnt[y] <= 0) { return []; } + cnt[y]--; ans.push(x); - cnt.set(x, (cnt.get(x) || 0) - 1); - cnt.set(x * 2, (cnt.get(x * 2) || 0) - 1); } - return ans.length == n / 2 ? ans : []; + return ans; } ``` diff --git a/solution/2000-2099/2007.Find Original Array From Doubled Array/README_EN.md b/solution/2000-2099/2007.Find Original Array From Doubled Array/README_EN.md index 23e1b3c2ab829..0554604e117cb 100644 --- a/solution/2000-2099/2007.Find Original Array From Doubled Array/README_EN.md +++ b/solution/2000-2099/2007.Find Original Array From Doubled Array/README_EN.md @@ -49,66 +49,59 @@ Other original arrays could be [4,3,1] or [3,1,4]. ## Solutions -### Solution 1: Sorting + Counting + Traversal +### Solution 1: Sorting -First, we check if the length $n$ of the array `changed` is odd. If it is, we directly return an empty array. +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. -Then, we sort the array `changed`, and use a hash table or array `cnt` to count the occurrence of each element in `changed`. +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. -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. +After the traversal, we return the answer array. -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. - -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`. +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`. ```python class Solution: def findOriginalArray(self, changed: List[int]) -> List[int]: - n = len(changed) - if n & 1: - return [] - cnt = Counter(changed) changed.sort() + cnt = Counter(changed) ans = [] for x in changed: if cnt[x] == 0: continue - if cnt[x * 2] <= 0: + cnt[x] -= 1 + if cnt[x << 1] <= 0: return [] + cnt[x << 1] -= 1 ans.append(x) - cnt[x] -= 1 - cnt[x * 2] -= 1 - return ans if len(ans) == n // 2 else [] + return ans ``` ```java class Solution { public int[] findOriginalArray(int[] changed) { int n = changed.length; - if (n % 2 == 1) { - return new int[] {}; - } Arrays.sort(changed); int[] cnt = new int[changed[n - 1] + 1]; for (int x : changed) { ++cnt[x]; } - int[] ans = new int[n / 2]; + int[] ans = new int[n >> 1]; int i = 0; for (int x : changed) { if (cnt[x] == 0) { continue; } - if (x * 2 >= cnt.length || cnt[x * 2] <= 0) { - return new int[] {}; + --cnt[x]; + int y = x << 1; + if (y >= cnt.length || cnt[y] <= 0) { + return new int[0]; } + --cnt[y]; ans[i++] = x; - cnt[x]--; - cnt[x * 2]--; } - return i == n / 2 ? ans : new int[] {}; + return ans; } } ``` @@ -117,41 +110,33 @@ class Solution { class Solution { public: vector findOriginalArray(vector& changed) { - int n = changed.size(); - if (n & 1) { - return {}; - } sort(changed.begin(), changed.end()); vector cnt(changed.back() + 1); - for (int& x : changed) { + for (int x : changed) { ++cnt[x]; } vector ans; - for (int& x : changed) { + for (int x : changed) { if (cnt[x] == 0) { continue; } - if (x * 2 >= cnt.size() || cnt[x * 2] <= 0) { + --cnt[x]; + int y = x << 1; + if (y >= cnt.size() || cnt[y] <= 0) { return {}; } + --cnt[y]; ans.push_back(x); - --cnt[x]; - --cnt[x * 2]; } - return ans.size() == n / 2 ? ans : vector(); + return ans; } }; ``` ```go -func findOriginalArray(changed []int) []int { - n := len(changed) - ans := []int{} - if n&1 == 1 { - return ans - } +func findOriginalArray(changed []int) (ans []int) { sort.Ints(changed) - cnt := make([]int, changed[n-1]+1) + cnt := make([]int, changed[len(changed)-1]+1) for _, x := range changed { cnt[x]++ } @@ -159,44 +144,39 @@ func findOriginalArray(changed []int) []int { if cnt[x] == 0 { continue } - if x*2 >= len(cnt) || cnt[x*2] <= 0 { + cnt[x]-- + y := x << 1 + if y >= len(cnt) || cnt[y] <= 0 { return []int{} } + cnt[y]-- ans = append(ans, x) - cnt[x]-- - cnt[x*2]-- } - if len(ans) != n/2 { - return []int{} - } - return ans + return } ``` ```ts function findOriginalArray(changed: number[]): number[] { - const n = changed.length; - if (n & 1) { - return []; - } - const cnt = new Map(); + changed.sort((a, b) => a - b); + const cnt: number[] = Array(changed.at(-1)! + 1).fill(0); for (const x of changed) { - cnt.set(x, (cnt.get(x) || 0) + 1); + ++cnt[x]; } - changed.sort((a, b) => a - b); const ans: number[] = []; for (const x of changed) { - if (cnt.get(x) == 0) { + if (cnt[x] === 0) { continue; } - if ((cnt.get(x * 2) || 0) <= 0) { + cnt[x]--; + const y = x << 1; + if (y >= cnt.length || cnt[y] <= 0) { return []; } + cnt[y]--; ans.push(x); - cnt.set(x, (cnt.get(x) || 0) - 1); - cnt.set(x * 2, (cnt.get(x * 2) || 0) - 1); } - return ans.length == n / 2 ? ans : []; + return ans; } ``` diff --git a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.cpp b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.cpp index 8919996635d5e..a0077efbbd4ff 100644 --- a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.cpp +++ b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.cpp @@ -1,27 +1,24 @@ class Solution { public: vector findOriginalArray(vector& changed) { - int n = changed.size(); - if (n & 1) { - return {}; - } sort(changed.begin(), changed.end()); vector cnt(changed.back() + 1); - for (int& x : changed) { + for (int x : changed) { ++cnt[x]; } vector ans; - for (int& x : changed) { + for (int x : changed) { if (cnt[x] == 0) { continue; } - if (x * 2 >= cnt.size() || cnt[x * 2] <= 0) { + --cnt[x]; + int y = x << 1; + if (y >= cnt.size() || cnt[y] <= 0) { return {}; } + --cnt[y]; ans.push_back(x); - --cnt[x]; - --cnt[x * 2]; } - return ans.size() == n / 2 ? ans : vector(); + return ans; } }; \ No newline at end of file diff --git a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.go b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.go index 78238bad71101..00e6edd341873 100644 --- a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.go +++ b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.go @@ -1,11 +1,6 @@ -func findOriginalArray(changed []int) []int { - n := len(changed) - ans := []int{} - if n&1 == 1 { - return ans - } +func findOriginalArray(changed []int) (ans []int) { sort.Ints(changed) - cnt := make([]int, changed[n-1]+1) + cnt := make([]int, changed[len(changed)-1]+1) for _, x := range changed { cnt[x]++ } @@ -13,15 +8,13 @@ func findOriginalArray(changed []int) []int { if cnt[x] == 0 { continue } - if x*2 >= len(cnt) || cnt[x*2] <= 0 { + cnt[x]-- + y := x << 1 + if y >= len(cnt) || cnt[y] <= 0 { return []int{} } + cnt[y]-- ans = append(ans, x) - cnt[x]-- - cnt[x*2]-- - } - if len(ans) != n/2 { - return []int{} } - return ans + return } \ No newline at end of file diff --git a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.java b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.java index b6702e8258c15..345f102473609 100644 --- a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.java +++ b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.java @@ -1,27 +1,25 @@ class Solution { public int[] findOriginalArray(int[] changed) { int n = changed.length; - if (n % 2 == 1) { - return new int[] {}; - } Arrays.sort(changed); int[] cnt = new int[changed[n - 1] + 1]; for (int x : changed) { ++cnt[x]; } - int[] ans = new int[n / 2]; + int[] ans = new int[n >> 1]; int i = 0; for (int x : changed) { if (cnt[x] == 0) { continue; } - if (x * 2 >= cnt.length || cnt[x * 2] <= 0) { - return new int[] {}; + --cnt[x]; + int y = x << 1; + if (y >= cnt.length || cnt[y] <= 0) { + return new int[0]; } + --cnt[y]; ans[i++] = x; - cnt[x]--; - cnt[x * 2]--; } - return i == n / 2 ? ans : new int[] {}; + return ans; } } \ No newline at end of file diff --git a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.py b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.py index f41d43969fea0..82d1037356812 100644 --- a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.py +++ b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.py @@ -1,17 +1,14 @@ class Solution: def findOriginalArray(self, changed: List[int]) -> List[int]: - n = len(changed) - if n & 1: - return [] - cnt = Counter(changed) changed.sort() + cnt = Counter(changed) ans = [] for x in changed: if cnt[x] == 0: continue - if cnt[x * 2] <= 0: + cnt[x] -= 1 + if cnt[x << 1] <= 0: return [] + cnt[x << 1] -= 1 ans.append(x) - cnt[x] -= 1 - cnt[x * 2] -= 1 - return ans if len(ans) == n // 2 else [] + return ans diff --git a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.ts b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.ts index 520577e4b6531..aacf2aad8ab1a 100644 --- a/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.ts +++ b/solution/2000-2099/2007.Find Original Array From Doubled Array/Solution.ts @@ -1,24 +1,21 @@ function findOriginalArray(changed: number[]): number[] { - const n = changed.length; - if (n & 1) { - return []; - } - const cnt = new Map(); + changed.sort((a, b) => a - b); + const cnt: number[] = Array(changed.at(-1)! + 1).fill(0); for (const x of changed) { - cnt.set(x, (cnt.get(x) || 0) + 1); + ++cnt[x]; } - changed.sort((a, b) => a - b); const ans: number[] = []; for (const x of changed) { - if (cnt.get(x) == 0) { + if (cnt[x] === 0) { continue; } - if ((cnt.get(x * 2) || 0) <= 0) { + cnt[x]--; + const y = x << 1; + if (y >= cnt.length || cnt[y] <= 0) { return []; } + cnt[y]--; ans.push(x); - cnt.set(x, (cnt.get(x) || 0) - 1); - cnt.set(x * 2, (cnt.get(x * 2) || 0) - 1); } - return ans.length == n / 2 ? ans : []; + return ans; }