LeetCode 题解工作台

等值距离和

给你一个下标从 0 开始的整数数组 nums 。现有一个长度等于 nums.length 的数组 arr 。对于满足 nums[j] == nums[i] 且 j != i 的所有 j , arr[i] 等于所有 |i - j| 之和。如果不存在这样的 j ,则令 arr[i] 等于 0 。 返回数…

category

3

题型

code_blocks

4

代码语言

hub

3

相关题

当前训练重点

中等 · 数组·哈希·扫描

bolt

答案摘要

我们先用哈希表 记录数组 中每个元素对应的下标列表,即 表示数组 中所有值为 的下标列表。 对于哈希表 中的每个值列表 ,我们可以计算出 中每个下标 对应的 的值。对于第一个下标 ,右边所有下标距离 的和 $right=\sum_{i=0}^{m-1} - idx[0] \times m$。接下来我们遍历 ,每一次计算得到 $ans[idx[i]] = left + right…

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 数组·哈希·扫描 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个下标从 0 开始的整数数组 nums 。现有一个长度等于 nums.length 的数组 arr 。对于满足 nums[j] == nums[i]j != i 的所有 jarr[i] 等于所有 |i - j| 之和。如果不存在这样的 j ,则令 arr[i] 等于 0

返回数组 arr

 

示例 1:

输入:nums = [1,3,1,1,2]
输出:[5,0,3,4,0]
解释:
i = 0 ,nums[0] == nums[2] 且 nums[0] == nums[3] 。因此,arr[0] = |0 - 2| + |0 - 3| = 5 。 
i = 1 ,arr[1] = 0 因为不存在值等于 3 的其他下标。
i = 2 ,nums[2] == nums[0] 且 nums[2] == nums[3] 。因此,arr[2] = |2 - 0| + |2 - 3| = 3 。
i = 3 ,nums[3] == nums[0] 且 nums[3] == nums[2] 。因此,arr[3] = |3 - 0| + |3 - 2| = 4 。 
i = 4 ,arr[4] = 0 因为不存在值等于 2 的其他下标。

示例 2:

输入:nums = [0,5,3]
输出:[0,0,0]
解释:因为 nums 中的元素互不相同,对于所有 i ,都有 arr[i] = 0 。

 

提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 109
lightbulb

解题思路

方法一:哈希表 + 前缀和

我们先用哈希表 dd 记录数组 numsnums 中每个元素对应的下标列表,即 d[x]d[x] 表示数组 numsnums 中所有值为 xx 的下标列表。

对于哈希表 dd 中的每个值列表 idxidx,我们可以计算出 idxidx 中每个下标 ii 对应的 arr[i]arr[i] 的值。对于第一个下标 idx[0]idx[0],右边所有下标距离 idx[0]idx[0] 的和 right=i=0m1idx[0]×mright=\sum_{i=0}^{m-1} - idx[0] \times m。接下来我们遍历 idxidx,每一次计算得到 ans[idx[i]]=left+rightans[idx[i]] = left + right,然后更新 leftleftrightright,即 left=left+(idx[i+1]idx[i])×(i+1)left = left + (idx[i+1] - idx[i]) \times (i+1),而 right=right(idx[i+1]idx[i])×(mi1)right = right - (idx[i+1] - idx[i]) \times (m-i-1)

遍历结束后,我们得到了数组 numsnums 中每个元素对应的 arrarr 的值,即 ansans

时间复杂度 O(n)O(n),空间复杂度 O(n)O(n)。其中 nn 为数组 numsnums 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution:
    def distance(self, nums: List[int]) -> List[int]:
        d = defaultdict(list)
        for i, x in enumerate(nums):
            d[x].append(i)
        ans = [0] * len(nums)
        for idx in d.values():
            left, right = 0, sum(idx) - len(idx) * idx[0]
            for i in range(len(idx)):
                ans[idx[i]] = left + right
                if i + 1 < len(idx):
                    left += (idx[i + 1] - idx[i]) * (i + 1)
                    right -= (idx[i + 1] - idx[i]) * (len(idx) - i - 1)
        return ans
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    The candidate demonstrates an understanding of using hash tables for efficient lookups.

  • question_mark

    The candidate considers optimizing the solution with prefix sums, showing awareness of performance constraints.

  • question_mark

    The candidate clearly explains the relationship between array scanning and hash lookup in this problem.

warning

常见陷阱

外企场景
  • error

    Overcomplicating the problem with unnecessary nested loops or recalculating distances multiple times.

  • error

    Not leveraging the power of hash tables for fast index lookups, which can lead to inefficient solutions.

  • error

    Failing to recognize the value of using a prefix sum approach, resulting in suboptimal performance for large arrays.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Modify the problem to consider different types of distance metrics, such as squared differences.

  • arrow_right_alt

    Instead of summing distances, return the maximum distance for each element's repeated occurrences.

  • arrow_right_alt

    Extend the problem to handle multidimensional arrays where the comparison of elements occurs across multiple axes.

help

常见问题

外企场景

等值距离和题解:数组·哈希·扫描 | LeetCode #2615 中等