leetcode
leetcode 151 ~ 200
缺失的区间

缺失的区间

难度:

标签:

题目描述

代码结果

运行时间: 20 ms, 内存: 0.0 MB


/*
 * Problem: Missing Ranges (LeetCode 163)
 * Given a sorted integer array nums, where the range of elements are in the inclusive range [lower, upper], return its missing ranges.
 * Example:
 * Input: nums = [0, 1, 3, 50, 75], lower = 0, upper = 99
 * Output: ["2", "4->49", "51->74", "76->99"]
 * 
 * Approach (Using Java Streams):
 * 1. Convert the nums array to a list and add lower-1 and upper+1 to handle the boundaries.
 * 2. Use IntStream.range to iterate through the list and find gaps between consecutive numbers.
 * 3. Collect the missing ranges into a result list.
 */
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
public class MissingRangesStream {
    public List<String> findMissingRanges(int[] nums, int lower, int upper) {
        List<Integer> list = new ArrayList<>();
        list.add(lower - 1);
        list.addAll(Arrays.stream(nums).boxed().collect(Collectors.toList()));
        list.add(upper + 1);
 
        return IntStream.range(0, list.size() - 1)
                .mapToObj(i -> formatRange(list.get(i) + 1, list.get(i + 1) - 1))
                .filter(range -> !range.isEmpty())
                .collect(Collectors.toList());
    }
 
    private String formatRange(int start, int end) {
        return (start <= end) ? (start == end ? String.valueOf(start) : start + "->" + end) : "";
    }
 
    public static void main(String[] args) {
        MissingRangesStream mrs = new MissingRangesStream();
        int[] nums = {0, 1, 3, 50, 75};
        int lower = 0;
        int upper = 99;
        System.out.println(mrs.findMissingRanges(nums, lower, upper));
    }
}

解释

方法:

这个题解的思路是先在原数组 nums 的首尾添加 lower-1 和 upper+1,这样可以方便处理缺失区间出现在数组两端的情况。然后遍历修改后的数组,如果相邻两个元素之差大于 2,说明它们之间存在缺失区间,将其记录到结果中。如果相邻元素之差等于 2,说明它们之间缺失了一个数,也将其记录到结果中。最后返回记录的所有缺失区间。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在原数组的首尾添加lower-1和upper+1,而不是直接使用lower和upper?这样添加有什么特别的好处?
在原数组首尾添加lower-1和upper+1,而不是直接使用lower和upper的主要原因是简化边界处理。通过添加这两个元素,可以保证数组两端的缺失区间能够被统一和简单地处理,无需单独考虑数组开头和结尾的情况。例如,如果数组中的第一个元素大于lower,通过添加lower-1,可以直接使用相同的逻辑来判断和添加从lower到第一个元素之前的缺失区间,而无需额外的条件判断。这种方法有效地减少了代码的复杂度并提高了可读性。
🦆
在处理数组为空的情况时,为何要单独考虑lower等于upper的情况,并且返回的结果格式是什么样的?
当数组为空时,整个区间[lower, upper]都是缺失的。单独考虑lower等于upper的情况是因为,当lower和upper相等时,缺失的区间不是一个范围而是一个具体的数字。因此,如果lower等于upper,结果应该直接返回这个单一的数字而非一个区间。返回的格式会是这个数字本身的字符串形式。如果lower不等于upper,则返回表示整个区间的字符串,如'lower->upper'。这种处理确保了返回的结果既准确又易于理解。
🦆
在遍历数组并记录缺失区间时,你是如何决定何时记录一个单独的数字而非一个区间的?
在遍历数组并记录缺失区间时,决定记录单独数字还是区间的依据在于相邻两个元素的差值。如果两个相邻元素的差值等于2,这意味着它们之间正好缺失一个数字,因此应记录这个单独的数字。例如,如果两个相邻元素是3和5,那么4是缺失的,应该被记录下来。如果差值大于2,比如3和6之间,那么缺失的是一个区间[4, 5],应记录为'4->5'。这种方法确保了所有类型的缺失都被正确记录。
🦆
在实际编码过程中,向数组中插入元素(如首部插入lower-1或尾部添加upper+1)可能会影响性能。你是如何考虑这种潜在影响的?
确实,向数组首部或尾部插入元素可能会影响性能,尤其是在数组较大时。首部插入元素特别可能导致数组内其他元素的移动,增加时间复杂度。为了减轻这种影响,可以考虑使用额外的变量来存储首尾的元素,而不是真的在数组中插入。另外,如果实际应用中性能成为关键问题,可以考虑使用链表等数据结构,这些结构允许在首尾快速插入元素而不影响性能。在算法设计时,需要根据具体情况权衡易用性和性能,选择最合适的实现方式。

相关问题

汇总区间

给定一个  无重复元素 的 有序 整数数组 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"

 

提示:

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