携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
题目链接:1200. 最小绝对差
题目描述
给你个整数数组 arr,其中每个元素都 不相同。
请你找到所有具有最小绝对差的元素对,并且按升序的顺序返回。
提示:
示例 1:
输入: arr = [4,2,1,3]
输出: [[1,2],[2,3],[3,4]]
示例 2:
输入: arr = [1,3,6,10,15]
输出: [[1,3]]
示例 3:
输入: arr = [3,8,-10,23,19,-4,-14,27]
输出: [[-14,-10],[19,23],[23,27]]
整理题意
题目给定一个整数数组 arr,要求我们找到数组中绝对差值最小的整数对,如果有多个,按升序的顺序返回这些数对。
解题思路分析
观察题目数据范围,数组元素个数在 以内,数据范围较大,无法通过暴力查找所有数对进行筛选,会超时 TLE。
既然题目要求将答案按照升序的顺序返回,那么我们可以先将数组进行排序处理。这样一来,可以发现「绝对差值最小」的元素对只能由有序数组中相邻的两个元素构成,从头到尾遍历一遍即可找到最小绝对差值,再遍历一遍数组即可找到数组中所有绝对差值最小的整数对,此时我们找到数组中绝对差值最小的整数对也是按升序的顺序排列好的,直接返回即可。
具体实现
- 首先对数组
arr进行从小到大排序处理。 - 第一次遍历寻找最小绝对差值
- 第二次遍历寻找绝对差值等于最小绝对差值的数对。
- 返回绝对差值等于最小差值的所有数对。
优化
这里还可以通过一次遍历完成:
- 遍历时记录最小差值的同时将等于当前最小差值数对放入答案数组;
- 当遇到更小的绝对差值时将答案数组清空,将当前数对放入答案数组;
- 循环遍历一遍即可得到绝对差值等于最小绝对差值的数对。
复杂度分析
- 时间复杂度:,其中
n是数组arr的长度。排序需要的时间为 ,遍历需要的是时间为 ,因此总时间复杂度为 。 - 空间复杂度:,即为排序需要使用的栈空间。这里不计入返回值需要使用的空间。
代码实现
class Solution {
public:
vector<vector<int>> minimumAbsDifference(vector<int>& arr) {
//升序排序
sort(arr.begin(), arr.end());
//记录最小绝对差值
int m = INT_MAX;
int n = arr.size();
for(int i = 1; i < n; i++){
m = min(m, arr[i] - arr[i - 1]);
}
//记录等于最小绝对差值的数对
vector<vector<int>> ans;
ans.clear();
for(int i = 1; i < n; i++){
if(arr[i] - arr[i - 1] == m){
vector<int> temp;
temp.clear();
temp.push_back(arr[i - 1]);
temp.push_back(arr[i]);
ans.push_back(temp);
}
}
return ans;
}
};
总结
- 通过观察题目数据范围,以及题目的提示,可以得知需要对数组进行排序处理;
- 排序后可以观察到最小绝对差值仅在相邻的两个整数之间出现。
- 通过遍历可以得到最小绝对差值的数对,这里利用了清空答案数组的方式,通过一次遍历即可得到答案。
- 测试结果:
结束语
无论是驱赶迷茫,还是对抗平庸,读书都是最简单也最实用的方法。阅读,犹如一场奇妙的旅行,总能带给我们丰富体验。给自己一点时间,静下心来读书,它会一点一滴地滋养你、改变你。新的一天,好好读书,加油!