第一题:原题链接:https://leetcode.cn/problems/summary-ranges/description/
代码:
class Solution {
public:
vector<string> summaryRanges(vector<int>& nums) {
vector<string> result;
int n = nums.size();
if (n == 0) return result;
int start = nums[0];
for (int i = 1; i < n; i++) {
// 差值判断是否连续
if ((long long)nums[i] - nums[i-1] != 1) {
// 使用 long long 防止负数溢出
if (start == nums[i-1]) {
result.push_back(to_string(start));
} else {
result.push_back(to_string(start) + "->" + to_string(nums[i-1]));
}
start = nums[i];
}
}
// 最后区间
if (start == nums.back()) {
result.push_back(to_string(start));
} else {
result.push_back(to_string(start) + "->" + to_string(nums.back()));
}
return result;
}
};
解题逻辑:
题目要求我们输出动态字符串数组,包含题设数组的所有连续区间。
需要遍历整个数组,每遍历一个数,判断是否与前区间nums[i-1]连续,若连续,则继续遍历;若不连续,则将前区间nums[i-1]截断,开始新区间判断。截断区间所用标志为start。
每次截断时,若start==nums[i-1],result.push_back(to_string(start)),如果不等,则result.push_back(to_string(start)+"->"+to_string(nums[i-1))。截断后,start更新为nums[i];
考察点:
- 整型推入字符串(to_string函数)
- 负数转正溢出(计算nums[i]-nums[i-1]时转换为long long)
- 不同区间衔接处理和最后区间处理
第二题:原题链接:https://leetcode.cn/problems/summary-ranges/description/
代码:
class Solution {
public:
long long countBadPairs(vector<int>& nums) {
long long count=0;
long long n=nums.size();
unordered_map<int,int> mymap;
if(n==1)return 0;
for(long long i=0;i<n;i++){
//i为已遍历个数
//i-mymap[nums[i]-i]为与mymap[nums[i]-i]不同的数即该答案的坏数对
count+=i-mymap[nums[i]-i];
//i-j!=nums[i]-nums[j]->nums[i]-i!=nums[j]-j;
mymap[nums[i]-i]++;
}
return count;
}
};
解题逻辑:
我们注意到,题目要求给出下标升序坏数对的数量,且数据较大,那么暴力遍历可能会超时,我们需要考虑一次遍历的解题办法,这里我们使用哈希表,利用其一个key对应一个值的性质快速解题。
同时,满足坏数对的条件为i-j!=nums[i]-nums[j],这与nums[i]-i!=nums[j]-j是等效的。因此我们在遍历时,只需要访问mymap[nums[i]-i]的值,再++mymap[nums[i]-i]。mymap[nums[i]-i]值就为好数对,那么i-mymap[nums[i]-i]的值就为坏数对。(i为已访问的数对量,i从1开始遍历)。
考察点:
- 条件变形能力:将i-j!=nums[i]-nums[j]变形为nums[i]-i!=nums[j]-j,将统计坏数对转换为数对-好数对。
- 哈希表统计思维。