From 3fcf1111198c72bdab419ccee59a6c4c48e95458 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 12 Dec 2023 17:12:26 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.2200 No.2200.Find All K-Distant Indices in an Array --- .../README.md | 253 ++++++++++++++++-- .../README_EN.md | 253 ++++++++++++++++-- .../Solution.cpp | 30 +-- .../Solution.go | 24 +- .../Solution.java | 28 +- .../Solution.py | 20 +- .../Solution.ts | 15 +- 7 files changed, 516 insertions(+), 107 deletions(-) diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md index 9a9f0f4eac49a..f238564b5fec8 100644 --- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md +++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README.md @@ -52,6 +52,26 @@ +**方法一:枚举** + +我们在 $[0, n)$ 的范围内枚举下标 $i$,对于每个下标 $i$,我们在 $[0, n)$ 的范围内枚举下标 $j$,如果 $|i - j| \leq k$ 且 $nums[j] == key$,那么 $i$ 就是一个 K 近邻下标,我们将 $i$ 加入答案数组中,然后跳出内层循环,枚举下一个下标 $i$。 + +时间复杂度 $O(n^2)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。 + +**方法二:预处理 + 二分查找** + +我们可以预处理得到所有等于 $key$ 的元素的下标,记录在数组 $idx$ 中。数组 $idx$ 中的所有下标元素是按照升序排列的, + +接下来,我们枚举下标 $i$,对于每个下标 $i$,我们可以使用二分查找的方法在数组 $idx$ 中查找 $[i - k, i + k]$ 范围内的元素,如果存在元素,那么 $i$ 就是一个 K 近邻下标,我们将 $i$ 加入答案数组中。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。 + +**方法三:双指针** + +我们枚举下标 $i$,用一个指针 $j$ 指向满足 $j \geq i - k$ 且 $nums[j] = key$ 的最小下标,如果 $j$ 存在且 $j \leq i + k$,那么 $i$ 就是一个 K 近邻下标,我们将 $i$ 加入答案数组中。 + +时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。 + ### **Python3** @@ -64,10 +84,34 @@ class Solution: ans = [] n = len(nums) for i in range(n): - for j in range(n): - if abs(i - j) <= k and nums[j] == key: - ans.append(i) - break + if any(abs(i - j) <= k and nums[j] == key for j in range(n)): + ans.append(i) + return ans +``` + +```python +class Solution: + def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]: + idx = [i for i, x in enumerate(nums) if x == key] + ans = [] + for i in range(len(nums)): + l = bisect_left(idx, i - k) + r = bisect_right(idx, i + k) - 1 + if l <= r: + ans.append(i) + return ans +``` + +```python +class Solution: + def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]: + ans = [] + j, n = 0, len(nums) + for i in range(n): + while j < i - k or (j < n and nums[j] != key): + j += 1 + if j < n and j <= (i + k): + ans.append(i) return ans ``` @@ -93,22 +137,45 @@ class Solution { } ``` -### **TypeScript** +```java +class Solution { + public List findKDistantIndices(int[] nums, int key, int k) { + List idx = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + if (nums[i] == key) { + idx.add(i); + } + } + List ans = new ArrayList<>(); + for (int i = 0; i < nums.length; ++i) { + int l = Collections.binarySearch(idx, i - k); + int r = Collections.binarySearch(idx, i + k + 1); + l = l < 0 ? -l - 1 : l; + r = r < 0 ? -r - 2 : r - 1; + if (l <= r) { + ans.add(i); + } + } + return ans; + } +} +``` -```ts -function findKDistantIndices(nums: number[], key: number, k: number): number[] { - const n = nums.length; - let ans = []; - for (let j = 0; j < n; j++) { - if (nums[j] == key) { - for (let i = j - k; i <= j + k; i++) { - if (i >= 0 && i < n && !ans.includes(i)) { - ans.push(i); - } +```java +class Solution { + public List findKDistantIndices(int[] nums, int key, int k) { + int n = nums.length; + List ans = new ArrayList<>(); + for (int i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] != key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.add(i); } } + return ans; } - return ans; } ``` @@ -133,15 +200,56 @@ public: }; ``` +```cpp +class Solution { +public: + vector findKDistantIndices(vector& nums, int key, int k) { + vector idx; + int n = nums.size(); + for (int i = 0; i < n; ++i) { + if (nums[i] == key) { + idx.push_back(i); + } + } + vector ans; + for (int i = 0; i < n; ++i) { + auto it1 = lower_bound(idx.begin(), idx.end(), i - k); + auto it2 = upper_bound(idx.begin(), idx.end(), i + k) - 1; + if (it1 <= it2) { + ans.push_back(i); + } + } + return ans; + } +}; +``` + +```cpp +class Solution { +public: + vector findKDistantIndices(vector& nums, int key, int k) { + int n = nums.size(); + vector ans; + for (int i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] != key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.push_back(i); + } + } + return ans; + } +}; +``` + ### **Go** ```go -func findKDistantIndices(nums []int, key int, k int) []int { - n := len(nums) - var ans []int - for i := 0; i < n; i++ { - for j, v := range nums { - if abs(i-j) <= k && v == key { +func findKDistantIndices(nums []int, key int, k int) (ans []int) { + for i := range nums { + for j, x := range nums { + if abs(i-j) <= k && x == key { ans = append(ans, i) break } @@ -158,6 +266,107 @@ func abs(x int) int { } ``` +```go +func findKDistantIndices(nums []int, key int, k int) (ans []int) { + idx := []int{} + for i, x := range nums { + if x == key { + idx = append(idx, i) + } + } + for i := range nums { + l := sort.SearchInts(idx, i-k) + r := sort.SearchInts(idx, i+k+1) - 1 + if l <= r { + ans = append(ans, i) + } + } + return +} +``` + +```go +func findKDistantIndices(nums []int, key int, k int) (ans []int) { + n := len(nums) + for i, j := 0, 0; i < n; i++ { + for j < i-k || (j < n && nums[j] != key) { + j++ + } + if j < n && j <= i+k { + ans = append(ans, i) + } + } + return +} +``` + +### **TypeScript** + +```ts +function findKDistantIndices(nums: number[], key: number, k: number): number[] { + const n = nums.length; + const ans: number[] = []; + for (let i = 0; i < n; ++i) { + for (let j = 0; j < n; ++j) { + if (Math.abs(i - j) <= k && nums[j] === key) { + ans.push(i); + break; + } + } + } + return ans; +} +``` + +```ts +function findKDistantIndices(nums: number[], key: number, k: number): number[] { + const n = nums.length; + const idx: number[] = []; + for (let i = 0; i < n; i++) { + if (nums[i] === key) { + idx.push(i); + } + } + const search = (x: number): number => { + let [l, r] = [0, idx.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (idx[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + const ans: number[] = []; + for (let i = 0; i < n; ++i) { + const l = search(i - k); + const r = search(i + k + 1) - 1; + if (l <= r) { + ans.push(i); + } + } + return ans; +} +``` + +```ts +function findKDistantIndices(nums: number[], key: number, k: number): number[] { + const n = nums.length; + const ans: number[] = []; + for (let i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] !== key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.push(i); + } + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md index e3a313b2917f7..c54cd518a8b59 100644 --- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md +++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/README_EN.md @@ -46,6 +46,26 @@ Hence, we return [0,1,2,3,4]. ## Solutions +**Solution 1: Enumeration** + +We enumerate the index $i$ in the range $[0, n)$, and for each index $i$, we enumerate the index $j$ in the range $[0, n)$. If $|i - j| \leq k$ and $nums[j] == key$, then $i$ is a K-nearest neighbor index. We add $i$ to the answer array, then break the inner loop and enumerate the next index $i$. + +The time complexity is $O(n^2)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + +**Solution 2: Preprocessing + Binary Search** + +We can preprocess to get the indices of all elements equal to $key$, recorded in the array $idx$. All index elements in the array $idx$ are sorted in ascending order. + +Next, we enumerate the index $i$. For each index $i$, we can use binary search to find elements in the range $[i - k, i + k]$ in the array $idx$. If there are elements, then $i$ is a K-nearest neighbor index. We add $i$ to the answer 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 $nums$. + +**Solution 3: Two Pointers** + +We enumerate the index $i$, and use a pointer $j$ to point to the smallest index that satisfies $j \geq i - k$ and $nums[j] = key$. If $j$ exists and $j \leq i + k$, then $i$ is a K-nearest neighbor index. We add $i$ to the answer array. + +The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + ### **Python3** @@ -56,10 +76,34 @@ class Solution: ans = [] n = len(nums) for i in range(n): - for j in range(n): - if abs(i - j) <= k and nums[j] == key: - ans.append(i) - break + if any(abs(i - j) <= k and nums[j] == key for j in range(n)): + ans.append(i) + return ans +``` + +```python +class Solution: + def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]: + idx = [i for i, x in enumerate(nums) if x == key] + ans = [] + for i in range(len(nums)): + l = bisect_left(idx, i - k) + r = bisect_right(idx, i + k) - 1 + if l <= r: + ans.append(i) + return ans +``` + +```python +class Solution: + def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]: + ans = [] + j, n = 0, len(nums) + for i in range(n): + while j < i - k or (j < n and nums[j] != key): + j += 1 + if j < n and j <= (i + k): + ans.append(i) return ans ``` @@ -83,22 +127,45 @@ class Solution { } ``` -### **TypeScript** +```java +class Solution { + public List findKDistantIndices(int[] nums, int key, int k) { + List idx = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + if (nums[i] == key) { + idx.add(i); + } + } + List ans = new ArrayList<>(); + for (int i = 0; i < nums.length; ++i) { + int l = Collections.binarySearch(idx, i - k); + int r = Collections.binarySearch(idx, i + k + 1); + l = l < 0 ? -l - 1 : l; + r = r < 0 ? -r - 2 : r - 1; + if (l <= r) { + ans.add(i); + } + } + return ans; + } +} +``` -```ts -function findKDistantIndices(nums: number[], key: number, k: number): number[] { - const n = nums.length; - let ans = []; - for (let j = 0; j < n; j++) { - if (nums[j] == key) { - for (let i = j - k; i <= j + k; i++) { - if (i >= 0 && i < n && !ans.includes(i)) { - ans.push(i); - } +```java +class Solution { + public List findKDistantIndices(int[] nums, int key, int k) { + int n = nums.length; + List ans = new ArrayList<>(); + for (int i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] != key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.add(i); } } + return ans; } - return ans; } ``` @@ -123,15 +190,56 @@ public: }; ``` +```cpp +class Solution { +public: + vector findKDistantIndices(vector& nums, int key, int k) { + vector idx; + int n = nums.size(); + for (int i = 0; i < n; ++i) { + if (nums[i] == key) { + idx.push_back(i); + } + } + vector ans; + for (int i = 0; i < n; ++i) { + auto it1 = lower_bound(idx.begin(), idx.end(), i - k); + auto it2 = upper_bound(idx.begin(), idx.end(), i + k) - 1; + if (it1 <= it2) { + ans.push_back(i); + } + } + return ans; + } +}; +``` + +```cpp +class Solution { +public: + vector findKDistantIndices(vector& nums, int key, int k) { + int n = nums.size(); + vector ans; + for (int i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] != key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.push_back(i); + } + } + return ans; + } +}; +``` + ### **Go** ```go -func findKDistantIndices(nums []int, key int, k int) []int { - n := len(nums) - var ans []int - for i := 0; i < n; i++ { - for j, v := range nums { - if abs(i-j) <= k && v == key { +func findKDistantIndices(nums []int, key int, k int) (ans []int) { + for i := range nums { + for j, x := range nums { + if abs(i-j) <= k && x == key { ans = append(ans, i) break } @@ -148,6 +256,107 @@ func abs(x int) int { } ``` +```go +func findKDistantIndices(nums []int, key int, k int) (ans []int) { + idx := []int{} + for i, x := range nums { + if x == key { + idx = append(idx, i) + } + } + for i := range nums { + l := sort.SearchInts(idx, i-k) + r := sort.SearchInts(idx, i+k+1) - 1 + if l <= r { + ans = append(ans, i) + } + } + return +} +``` + +```go +func findKDistantIndices(nums []int, key int, k int) (ans []int) { + n := len(nums) + for i, j := 0, 0; i < n; i++ { + for j < i-k || (j < n && nums[j] != key) { + j++ + } + if j < n && j <= i+k { + ans = append(ans, i) + } + } + return +} +``` + +### **TypeScript** + +```ts +function findKDistantIndices(nums: number[], key: number, k: number): number[] { + const n = nums.length; + const ans: number[] = []; + for (let i = 0; i < n; ++i) { + for (let j = 0; j < n; ++j) { + if (Math.abs(i - j) <= k && nums[j] === key) { + ans.push(i); + break; + } + } + } + return ans; +} +``` + +```ts +function findKDistantIndices(nums: number[], key: number, k: number): number[] { + const n = nums.length; + const idx: number[] = []; + for (let i = 0; i < n; i++) { + if (nums[i] === key) { + idx.push(i); + } + } + const search = (x: number): number => { + let [l, r] = [0, idx.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (idx[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + const ans: number[] = []; + for (let i = 0; i < n; ++i) { + const l = search(i - k); + const r = search(i + k + 1) - 1; + if (l <= r) { + ans.push(i); + } + } + return ans; +} +``` + +```ts +function findKDistantIndices(nums: number[], key: number, k: number): number[] { + const n = nums.length; + const ans: number[] = []; + for (let i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] !== key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.push(i); + } + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp index d5fa87ca2d76a..58c3adb6840c8 100644 --- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp +++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.cpp @@ -1,16 +1,16 @@ -class Solution { -public: - vector findKDistantIndices(vector& nums, int key, int k) { - int n = nums.size(); - vector ans; - for (int i = 0; i < n; ++i) { - for (int j = 0; j < n; ++j) { - if (abs(i - j) <= k && nums[j] == key) { - ans.push_back(i); - break; - } - } - } - return ans; - } +class Solution { +public: + vector findKDistantIndices(vector& nums, int key, int k) { + int n = nums.size(); + vector ans; + for (int i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] != key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.push_back(i); + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go index 387499f236a09..9f87a7fe27a93 100644 --- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go +++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.go @@ -1,20 +1,12 @@ -func findKDistantIndices(nums []int, key int, k int) []int { +func findKDistantIndices(nums []int, key int, k int) (ans []int) { n := len(nums) - var ans []int - for i := 0; i < n; i++ { - for j, v := range nums { - if abs(i-j) <= k && v == key { - ans = append(ans, i) - break - } + for i, j := 0, 0; i < n; i++ { + for j < i-k || (j < n && nums[j] != key) { + j++ + } + if j < n && j <= i+k { + ans = append(ans, i) } } - return ans -} - -func abs(x int) int { - if x < 0 { - return -x - } - return x + return } \ No newline at end of file diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java index 4e3632276d4c5..9dddaba757419 100644 --- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java +++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.java @@ -1,15 +1,15 @@ -class Solution { - public List findKDistantIndices(int[] nums, int key, int k) { - int n = nums.length; - List ans = new ArrayList<>(); - for (int i = 0; i < n; ++i) { - for (int j = 0; j < n; ++j) { - if (Math.abs(i - j) <= k && nums[j] == key) { - ans.add(i); - break; - } - } - } - return ans; - } +class Solution { + public List findKDistantIndices(int[] nums, int key, int k) { + int n = nums.length; + List ans = new ArrayList<>(); + for (int i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] != key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.add(i); + } + } + return ans; + } } \ No newline at end of file diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py index 79e0217d9cf33..b552876bbed4e 100644 --- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py +++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.py @@ -1,10 +1,10 @@ -class Solution: - def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]: - ans = [] - n = len(nums) - for i in range(n): - for j in range(n): - if abs(i - j) <= k and nums[j] == key: - ans.append(i) - break - return ans +class Solution: + def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]: + ans = [] + j, n = 0, len(nums) + for i in range(n): + while j < i - k or (j < n and nums[j] != key): + j += 1 + if j < n and j <= (i + k): + ans.append(i) + return ans diff --git a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts index ec9507f3f68f5..85fd8fe4a5796 100644 --- a/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts +++ b/solution/2200-2299/2200.Find All K-Distant Indices in an Array/Solution.ts @@ -1,13 +1,12 @@ function findKDistantIndices(nums: number[], key: number, k: number): number[] { const n = nums.length; - let ans = []; - for (let j = 0; j < n; j++) { - if (nums[j] == key) { - for (let i = j - k; i <= j + k; i++) { - if (i >= 0 && i < n && !ans.includes(i)) { - ans.push(i); - } - } + const ans: number[] = []; + for (let i = 0, j = 0; i < n; ++i) { + while (j < i - k || (j < n && nums[j] !== key)) { + ++j; + } + if (j < n && j <= i + k) { + ans.push(i); } } return ans;