汇总区间
汇总区间
给定一个无重复元素的有序整数数组nums
。
返回恰好覆盖数组中所有数字的最小有序区间范围列表。也就是说,nums
的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于nums
的数字x
。
列表中的每个区间范围[a,b]
应该按如下格式输出:
"a->b"
,如果a != b
。"a"
,如果a == b
。
示例
输入:nums = [0,1,2,4,5,7]
输出:["0->2","4->5","7"]
解释:区间范围是:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"
输入:nums = [0,2,3,4,6,8,9]
输出:["0","2->4","6","8->9"]
解释:区间范围是:
[0,0] --> "0"
[2,4] --> "2->4"
[6,6] --> "6"
[8,9] --> "8->9"
输入:nums = []
输出:[]
输入:nums = [-1]
输出:["-1"]
输入:nums = [0]
输出:["0"]
题解
/**
* @param {number[]} nums
* @return {string[]}
*/
var summaryRanges = function(nums) {
const n = nums.length;
if(n === 0) return nums;
if(n === 1) return [String(nums[0])];
let left = nums[0];
let right = nums[0];
const target = [];
for (let i=1; i<=n; i++){
const cur = nums[i];
const pre = nums[i-1];
if (cur - pre === 1){
right = cur;
}else if(left === right){
target.push(String(left));
left = cur;
right = cur;
}else{
target.push([left, "->", right].join(""));
left = cur;
right = cur;
}
}
return target;
};
/**
var summaryRanges = function(nums) {
const n = nums.length;
if(n === 0) return nums;
if(n === 1) return [String(nums[0])];
let sequence = nums[0];
let unit = [sequence];
let pre = sequence;
const target = [];
nums.forEach((v, i) => {
if(v !== sequence++){
if(unit[0] !== pre) unit.push(pre);
sequence = v + 1;
target.push(unit.join("->"));
unit = [v];
}
pre = v;
})
if(unit[0] !== nums[n-1]) unit.push(nums[n-1]);
target.push(unit.join("->"))
return target;
};
*/
思路
本题特别需要注意的情况就是当两个值相等的时候只放置一个值即可,在上述题解下边就是我之前的思路,使用了一个递增的序列值作为与原序列值的对比来完成,需要特殊处理在两个值相同时的情况,上边是新的思路,思路相对更加简单,使用两个指针,差值为一则右指针就前进一格,差值大于一就推一个区间进数组,然后左右指针同时指向下一个值继续遍历即可。首先定义数组长度,之后判断如果数组长度为0
则直接返回,如果数组长度为1
则返回其中的值并需要将值转为字符串类型,之后定义左右指针分别指向第一个值,定义目标数组,建立循环,在Js
中不必过多担心越界的情况,在后边比较时只需要将其当作undefined
处理,之后定义当前值与前一个值,如果这两个值差值为1
就将右指针右移,如果两个指针相等则将其中一个值转为字符串类型并推入目标数组,并将两个指针设置为当前值,如果差值不是1
且不相同,则将其拼接为要求的字符串推入数组,并将两个指针设置为当前值,循环结束返回目标数组即可。
每日一题
https://github.com/WindrunnerMax/EveryDay
参考
https://leetcode-cn.com/problems/summary-ranges/