LeetCode笔记:汇总区间

问题

给定一个无重复元素的有序整数数组 nums

返回 恰好覆盖数组中所有数字最小有序 区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x

列表中的每个区间范围 [a,b] 应该按如下格式输出:

  • "a->b" ,如果 a != b
  • "a" ,如果 a == b

示例 1:

输入: nums = [0,1,2,4,5,7]

输出: ["0->2","4->5","7"]

解释: 区间范围是:

[0,2] --> "0->2"

[4,5] --> "4->5"

[7,7] --> "7"

示例 2:

输入: 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"

示例 3:

输入: nums = []

输出: []

示例 4:

输入: nums = [-1]

输出: ["-1"]

示例 5:

输入: nums = [0]

输出: ["0"]

提示:

  • 0 <= nums.length <= 20
  • -231 <= nums[i] <= 231 - 1
  • nums 中的所有值都 互不相同
  • nums 按升序排列

解法

思路:

使用reduce方法遍历整个数组,关键在于比较当前数字是不是比上一个数字大 1,只有大于 1 的时候,当前数字才是和上一个数字是同一组合的,否则就要新建一个数组。

代码:

/**
 * @param {number[]} nums
 * @return {string[]}
 */
var summaryRanges = function (nums) {
  // 特殊情况,空数组直接返回
  if (nums.length === 0) return nums;

  // 设定一个临时数组,存放一个完整的数组区间,初始化为第一个数字
  let preArr = [nums[0]];

  // 结果数组
  const resultArr = [];

  // 使用reduce来便捷比较当前数字和上一个数字
  nums.reduce((pre, cur) => {
    // 只有当前数字比上一个数字递增1,才属于同一个完整的区间
    if (pre + 1 === cur) {
      preArr.push(cur);
    } else {
      // 否则需要将上一个完整的区间存储进结果数组中,再重新初始化一个新的完整区间
      resultArr.push(preArr);
      preArr = [cur];
    }

    // 必须返回当前数字,才能将当前数字传递到下一次循环中做比较
    return cur;
  });

  // 最后一个完整区间因为没有在上面reduce循环中截获到,所以在这里单独存储
  resultArr.push(preArr);

  // 调用转换方法
  return transformArr(resultArr);

  // 转换方法
  // 将数组转换为题目要求的格式
  // [1,2,3] => '1->3'
  // [1] => '1'
  function transformArr(arr) {
    return arr.map((cur, index) => {
      if (cur.length === 1) {
        return cur.shift() + "";
      } else {
        return cur.shift() + "->" + cur.pop();
      }
    });
  }
};

参考

评论