Easy

题目描述

给你一个整数数组 nums (下标从 0 开始)和两个整数 targetstart,请你找出一个下标 i,使得 nums[i] == targetabs(i - start) 的值最小。注意 abs(x) 表示 x 的绝对值。

返回 abs(i - start)

题目数据保证 target 存在于 nums 中。

示例 1:

输入:nums = [1,2,3,4,5], target = 5, start = 3
输出:1
解释:nums[4] = 5 是唯一一个等于 target 的值,所以答案是 abs(4 - 3) = 1 。

示例 2:

输入:nums = [1], target = 1, start = 0
输出:0
解释:nums[0] = 1 是唯一一个等于 target 的值,所以答案是 abs(0 - 0) = 0 。

示例 3:

输入:nums = [1,1,1,1,1,1,1,1,1,1], target = 1, start = 0
输出:0
解释:nums 中每个值都是 1 ,但 nums[0] 使 abs(i - start) 的值最小,为 abs(0 - 0) = 0 。

提示:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 10^4
  • 0 <= start < nums.length
  • target 存在于 nums

解题思路

这道题要求找到数组中等于目标值且距离起始位置最近的元素索引。

解法分析

方法一:暴力遍历 最直接的方法是遍历整个数组,找到所有等于 target 的元素,计算它们与 start 的距离,返回最小距离。

方法二:双向扩展(推荐) 从 start 位置开始,向左右两个方向同时扩展搜索。这样一旦找到目标元素,就能保证是距离最近的,可以立即返回结果,避免不必要的遍历。

具体实现:

  1. 首先检查 start 位置是否就是目标值
  2. 然后同时向左右扩展,distance 从 1 开始递增
  3. 检查 start-distance 和 start+distance 位置的值
  4. 一旦找到目标值立即返回当前距离

双向扩展的优势在于:

  • 时间复杂度在最好情况下可以达到 O(1)
  • 平均情况下比暴力遍历更快
  • 代码逻辑清晰,易于理解

方法三:分别向左右查找 也可以分别向左和向右查找最近的目标元素,然后比较两个距离取最小值。

代码实现

class Solution {
public:
    int getMinDistance(vector<int>& nums, int target, int start) {
        int n = nums.size();
        
        // 从start位置开始双向扩展
        for (int distance = 0; distance < n; distance++) {
            // 检查左边
            if (start - distance >= 0 && nums[start - distance] == target) {
                return distance;
            }
            // 检查右边
            if (start + distance < n && nums[start + distance] == target) {
                return distance;
            }
        }
        
        return -1; // 不会执行到这里,因为题目保证target存在
    }
};
class Solution:
    def getMinDistance(self, nums: List[int], target: int, start: int) -> int:
        n = len(nums)
        
        # 从start位置开始双向扩展
        for distance in range(n):
            # 检查左边
            if start - distance >= 0 and nums[start - distance] == target:
                return distance
            # 检查右边
            if start + distance < n and nums[start + distance] == target:
                return distance
        
        return -1  # 不会执行到这里,因为题目保证target存在
public class Solution {
    public int GetMinDistance(int[] nums, int target, int start) {
        int n = nums.Length;
        
        // 从start位置开始双向扩展
        for (int distance = 0; distance < n; distance++) {
            // 检查左边
            if (start - distance >= 0 && nums[start - distance] == target) {
                return distance;
            }
            // 检查右边
            if (start + distance < n && nums[start + distance] == target) {
                return distance;
            }
        }
        
        return -1; // 不会执行到这里,因为题目保证target存在
    }
}
var getMinDistance = function(nums, target, start) {
    const n = nums.length;
    
    // 从start位置开始双向扩展
    for (let distance = 0; distance < n; distance++) {
        // 检查左边
        if (start - distance >= 0 && nums[start - distance]

复杂度分析

复杂度类型分析
时间复杂度O(n),最坏情况下需要遍历整个数组,但平均情况下会更快
空间复杂度O(1),只使用常数级额外空间