2200.找出数组中的所有 K 近邻下标:O(n)解法 - 比灵神代码简洁了一回

【LetMeFly】2200.找出数组中的所有 K 近邻下标:O(n)解法 - 比灵神代码简洁了一回

力扣题目链接:https://leetcode.cn/problems/find-all-k-distant-indices-in-an-array/

给你一个下标从 0 开始的整数数组 nums 和两个整数 keykK 近邻下标nums 中的一个下标 i ,并满足至少存在一个下标 j 使得 |i - j| <= knums[j] == key

以列表形式返回按 递增顺序 排序的所有 K 近邻下标。

 

示例 1:

输入:nums = [3,4,9,1,3,9,5], key = 9, k = 1
输出:[1,2,3,4,5,6]
解释:因此,nums[2] == keynums[5] == key 。
- 对下标 0 ,|0 - 2| > k 且 |0 - 5| > k ,所以不存在 j 使得 |0 - j| <= knums[j] == key 。所以 0 不是一个 K 近邻下标。
- 对下标 1 ,|1 - 2| <= k 且 nums[2] == key ,所以 1 是一个 K 近邻下标。
- 对下标 2 ,|2 - 2| <= k 且 nums[2] == key ,所以 2 是一个 K 近邻下标。
- 对下标 3 ,|3 - 2| <= k 且 nums[2] == key ,所以 3 是一个 K 近邻下标。
- 对下标 4 ,|4 - 5| <= k 且 nums[5] == key ,所以 4 是一个 K 近邻下标。
- 对下标 5 ,|5 - 5| <= k 且 nums[5] == key ,所以 5 是一个 K 近邻下标。
- 对下标 6 ,|6 - 5| <= k 且 nums[5] == key ,所以 6 是一个 K 近邻下标。
因此,按递增顺序返回 [1,2,3,4,5,6] 。 

示例 2:

输入:nums = [2,2,2,2,2], key = 2, k = 2
输出:[0,1,2,3,4]
解释:对 nums 的所有下标 i ,总存在某个下标 j 使得 |i - j| <= k 且 nums[j] == key ,所以每个下标都是一个 K 近邻下标。 
因此,返回 [0,1,2,3,4] 。

 

提示:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 1000
  • key 是数组 nums 中的一个整数
  • 1 <= k <= nums.length

解题方法一:暴力模拟

用$i$从$0$到$len(nums)-1$遍历$nums$中的每个数并分别判断他们是否是“K近邻下标”,用$j$从$max(0, i-k)$到$min(len(nums)-1, i+k)$判断$i$的“K临近”是否有值为key的元素,如果有就将i添加到答案数组中。

  • 时间复杂度$O(len(nums)\times k)$
  • 空间复杂度$O(1)$,力扣返回值不计入算法空间复杂度

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* @Author: LetMeFly
* @Date: 2025-06-25 22:24:22
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-06-25 22:29:22
*/
class Solution {
public:
vector<int> findKDistantIndices(vector<int>& nums, int key, int k) {
vector<int> ans;
for (int i = 0; i < nums.size(); i++) {
for (int j = max(0, i - k); j <= min(int(nums.size()) - 1, i + k); j++) {
if (nums[j] == key) {
ans.push_back(i);
break;
}
}
}
return ans;
}
};

解题方法二:双指针

我们不妨换个思路,遍历数组并将值为key的附近元素下标添加到答案数组中。

一个指针$i$遍历$nums$数组,一个指针$j$指向“未判断过的元素”。所谓“未判断过的元素”是指还不知道这个元素是否可以被加入答案数组。

如果$i$遍历到了值为$key$的元素了如何做?就将$[j, min(len(nums)-1, i+k)]$全部添加到答案数组中。

也就是说,$i$指针遍历了数组一次,$j$指针最多遍历每个元素各一次,总时间复杂度降低至了$O(n)$

  • 时间复杂度$O(len(nums))$
  • 空间复杂度$O(1)$,力扣返回值不计入算法空间复杂度

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* @Author: LetMeFly
* @Date: 2025-06-25 22:30:38
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-06-25 22:34:30
*/
class Solution {
public:
vector<int> findKDistantIndices(vector<int>& nums, int key, int k) {
vector<int> ans;
for (int i = 0, j = 0; i < nums.size(); i++) {
if (nums[i] == key) {
int l = max(j, i - k), r = min(i + k, (int)nums.size() - 1);
for (j = l; j <= r; j++) {
ans.push_back(j);
}
}
}
return ans;
}
};

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'''
Author: LetMeFly
Date: 2025-06-25 22:24:22
LastEditors: LetMeFly.xyz
LastEditTime: 2025-06-25 22:38:19
'''
from typing import List

class Solution:
def findKDistantIndices(self, nums: List[int], key: int, k: int) -> List[int]:
ans = []
last = 0
for i in range(len(nums)):
if nums[i] == key:
for j in range(max(last, i - k), min(len(nums), i + k + 1)):
ans.append(j)
last = i + k + 1
return ans

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
* @Author: LetMeFly
* @Date: 2025-06-25 22:24:22
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-06-25 22:41:09
*/
import java.util.List;
import java.util.ArrayList;

class Solution {
public List<Integer> findKDistantIndices(int[] nums, int key, int k) {
List<Integer> ans = new ArrayList<>();
for (int i = 0, j = 0; i < nums.length; i++) {
if (nums[i] == key) {
for (j = Math.max(j, i - k); j <= Math.min(nums.length - 1, i + k); j++) {
ans.add(j);
}
}
}
return ans;
}
}

Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
* @Author: LetMeFly
* @Date: 2025-06-25 22:24:22
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-06-25 22:43:42
*/
package main

func findKDistantIndices(nums []int, key int, k int) (ans []int) {
for i, j := 0, 0; i < len(nums); i++ {
if nums[i] == key {
for j = max(j, i - k); j <= min(len(nums) - 1, i + k); j++ {
ans = append(ans, j)
}
}
}
return
}

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源


2200.找出数组中的所有 K 近邻下标:O(n)解法 - 比灵神代码简洁了一回
https://blog.letmefly.xyz/2025/06/25/LeetCode 2200.找出数组中的所有K近邻下标/
作者
发布于
2025年6月25日
许可协议