2121. 相同元素的间隔之和

简介: 笔记

1. 题意


给定一个数组 arr ,定义两个元素的间隔是数组中与该元素的值相同的位置之差。

即:dis = | i - j | ,(arr[i] == arr[j])

返回每位数的间隔之和


样例

输入:arr = [2,1,3,1,2,3,3]

输出:[4,2,7,2,4,4,5]

解释:

下标 0 :另一个 2 在下标 4 ,|0 - 4| = 4

下标 1 :另一个 1 在下标 3 ,|1 - 3| = 2

下标 2 :另两个 3 在下标 5 和 6 ,|2 - 5| + |2 - 6| = 7

下标 3 :另一个 1 在下标 1 ,|3 - 1| = 2

下标 4 :另一个 2 在下标 0 ,|4 - 0| = 4

下标 5 :另两个 3 在下标 2 和 6 ,|5 - 2| + |5 - 6| = 4

下标 6 :另两个 3 在下标 2 和 5 ,|6 - 2| + |6 - 5| = 5


输入:arr = [10,5,10,10]

输出:[5,0,3,4]

解释:

下标 0 :另两个 10 在下标 2 和 3 ,|0 - 2| + |0 - 3| = 5

下标 1 :只有这一个 5 在数组中,所以到相同元素的间隔之和是 0

下标 2 :另两个 10 在下标 0 和 3 ,|2 - 0| + |2 - 3| = 3

下标 3 :另两个 10 在下标 0 和 2 ,|3 - 0| + |3 - 2| = 4


2. 思路



对每位数拉链,vector存储元素 x 的依次的位置

前缀和 + 后缀和

/* 相同元素的下标为数组p: p0   p1   p2   p3   p4
   两两间隔为:               a    b   c    d
   ans[0] = p4-p0 + p3-p0 + p2-p0 + p1 - p0
          = 0           +    4a+3b+2c+1d  
   ans[1] = a           +       3b+2c+1d
   ans[2] = a+2b        +          2c+1d
   ans[3] = a+2b+3c     +             1d
   ans[4] = a+2b+3c+4d  +              0
   从上可以看出规律, 使用前缀和leftSum和后缀和rightSum, 进行优化计算;
*/

一遍递推过去

先遍历一次 v, 计算出第一个元素(位置为 0)到其余元素的间隔和


第二次遍历,不断向右计算下一个元素的间隔和。


第 i - 1 个元素到第 i 个元素,间隔和变化:


左边有 i 个元素,间隔和变大 v[i] - v[i - 1]

右边有 n - i 个元素, 间隔和变小 v[i] - v[i - 1]

总间隔和变化量:(2 * i - n) * (v[i] - v[i - 1])

3. 算法


哈希 + 前缀和

4. 代码


代码1

class Solution {
public:
    typedef long long ll;
    vector<long long> getDistances(vector<int>& arr) {
        vector<ll> ans(arr.size());
        map<int, vector<ll> > mp;
        for (int i = 0; i < arr.size(); i++) {
            int x = arr[i];
            mp[x].push_back(i);
        }
        for (auto &[k, v]: mp) {
            int n = v.size();
            ll suffix = 0, prefix = 0; // 后缀 & 前缀
            vector<ll> diff(n); // 相邻元素间隔差
            for (int i = 0; i < n - 1; i++)  
                diff[i] = v[i + 1] - v[i];
            for (int i = n - 2; i >= 0; i--) // 计算后缀 4a + 3b + 2c + d
                suffix += diff[i] * (n - i - 1);
            ans[v[0]] = suffix; // 第一个位置的值就是整个后缀
            for (int i = 1; i < n; i++) {
                prefix += i * diff[i - 1]; // 前缀计算
                suffix -= (n - i) * diff[i - 1]; // 后缀变化
                ans[v[i]] = prefix + suffix; // 每一位的值
            }
        }
        return ans;
    }
};

代码2

class Solution {
public:
    typedef long long ll;
    vector<long long> getDistances(vector<int>& arr) {
        vector<ll> ans(arr.size());
        map<int, vector<ll> > mp;
        for (int i = 0; i < arr.size(); i++) {
            mp[arr[i]].push_back(i);
        }
        for (auto &[k, v]: mp) {
            int n = v.size();
            ll sum = 0;
            for (int i = 0; i < n; i++)
                sum += v[i] - v[0];
            ans[v[0]] = sum;
            for (int i = 1; i < n; i++) {
                sum += (2 * i - n) * (v[i] - v[i - 1]);
                ans[v[i]] = sum;
            }
        }
        return ans;
    }
};
相关文章
|
存储 缓存 Java
线程同步的艺术:探索 JAVA 主流锁的奥秘
本文介绍了 Java 中的锁机制,包括悲观锁与乐观锁的并发策略。悲观锁假设多线程环境下数据冲突频繁,访问前先加锁,如 `synchronized` 和 `ReentrantLock`。乐观锁则在访问资源前不加锁,通过版本号或 CAS 机制保证数据一致性,适用于冲突少的场景。锁的获取失败时,线程可以选择阻塞(如自旋锁、适应性自旋锁)或不阻塞(如无锁、偏向锁、轻量级锁、重量级锁)。此外,还讨论了公平锁与非公平锁,以及可重入锁与非可重入锁的特性。最后,提到了共享锁(读锁)和排他锁(写锁)的概念,适用于不同类型的并发访问需求。
330 2
|
测试技术
JMeter笔记12 | JMeter集合点
JMeter笔记12 | JMeter集合点
212 0
JMeter笔记12 | JMeter集合点
|
数据可视化 关系型数据库 MySQL
mysql:解压版MySQL通过SQLyog可视化密码过期问题(错误号码1862)
mysql:解压版MySQL通过SQLyog可视化密码过期问题(错误号码1862)
509 0
mysql:解压版MySQL通过SQLyog可视化密码过期问题(错误号码1862)
|
算法 数据挖掘
决策树算法之分类回归树 CART(Classification and Regression Trees)【2】
[上一篇](https://www.atatech.org/articles/158334)文章主要介绍了分类树,下面我们再一起来看一下回归树,我们知道,分类决策树的叶子节点即为分类的结果;同理,回归树的叶子节点便是连续的预测值。那么,同样是回归算法,线性回归和决策树回归有什么区别呢?区别在于,前者拟合的是一条直线,而后者却可以拟合非线性的数据,如下图中的数据就是用线性回归来拟合的: ![]
|
Java jenkins 持续交付
|
10天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1211 5
|
9天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1173 87

热门文章

最新文章