闻缺陷则喜何志丹

闻缺陷则喜何志丹

本文涉及的基础知识点

基础数学

LeetCode2121. 相同元素的间隔之和

难度分:1760
令2165,和此题几乎相等。
给你一个下标从 0 开始、由 n 个整数组成的数组 arr 。
arr 中两个元素的 间隔 定义为它们下标之间的 绝对差 。更正式地,arr[i] 和 arr[j] 之间的间隔是 |i - j| 。
返回一个长度为 n 的数组 intervals ,其中 intervals[i] 是 arr[i] 和 arr 中每个相同元素(与 arr[i] 的值相同)的 间隔之和 。
注意:|x| 是 x 的绝对值。
示例 1:
输入: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
    示例 2:

输入: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
    提示:
    n == arr.length
    1 <= n <= 10
    1 <= arr[i] <= 10

C++

indexs[i] 记录nums中所有值为i的下标。令 v = indexs[i]。
v[0]的距离各下标的和为: ∑ i : v . s i z e ( ) − 1 ( v [ i ] − v [ 0 ] ) \sum_{i:}^{v.size()-1}(v[i]-v[0]) i:v.size()1(v[i]v[0]) v[j]也可以这样计算,但这样做的总时间复杂度是:O(nn)。
可以通过v[i] 计算v[i+1]:
令有n1个下标<i,有n2个下标大于i+1。
n1个下标 的距离增加了: v[i+1]- v[i]
n2个下标的距离减少了: v[i+1]- v[i]
即:v[i+1]的总距离 = v[i]的总距离+ (n1-n2)*( v[i+1]- v[i])
n1 =i n2 = n - i -2

代码

核心代码

class Solution {
		public:
			vector<long long> getDistances(vector<int>& arr) {
				const int N = arr.size();
				vector<vector<int>> indexs(100'000 + 1);
				for (int i = 0; i < arr.size(); i++) {
					indexs[arr[i]].emplace_back(i);
				}
				vector<long long> ret(arr.size());
				for (const auto& v : indexs) {
					if (v.empty()) { continue; }
					long long cur = accumulate(v.begin(), v.end(), 0LL) - (long long)v.front() * v.size();
					ret[v[0]] = cur;
					for (int i = 0; i + 1 < v.size(); i++) {
						ret[v[i + 1]] = ret[v[i]] + ((long long)i-(v.size() - i - 2 )) * ((long long)v[i + 1] - v[i]);
					}
				}
				return ret;
			}
		};

单元测试

vector<int> arr;
		TEST_METHOD(TestMethod11)
		{
			arr = { 2, 1, 3, 1, 2, 3, 3 };
			auto res = Solution().getDistances(arr);
			AssertEx(vector<long long>{4, 2, 7, 2, 4, 4, 5}, res);
		}
		TEST_METHOD(TestMethod12)
		{
			arr = { 10,5,10,10 };
			auto res = Solution().getDistances(arr);
			AssertEx(vector<long long>{5,0,3,4}, res);
		}

【C++ 基础数学 】2121. 2615相同元素的间隔之和|1760-LMLPHP

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

【C++ 基础数学 】2121. 2615相同元素的间隔之和|1760-LMLPHP

09-24 22:58