首页 > 技术文章 > [LeetCode#163] Missing Ranges

airwindow 2015-09-10 08:43 原文

Problem:

Given a sorted integer array where the range of elements are [lowerupper] inclusive, return its missing ranges.

For example, given [0, 1, 3, 50, 75]lower = 0 and upper = 99, return ["2", "4->49", "51->74", "76->99"].

General Analysis:

This kind problem is easy, it just test your proramming skills.
Basic idea:
According to the problem, the gap between two numbers: nums[i], nums[i+1] should be recorded.
There could be following situation:
------------------------------------------------------------------------------------------------
case 1: no gap (nums[i] + 1 == nums[i+1])
We need to record nothing.
------------------------------------------------------------------------------------------------
case 2: the gap's length is 1. (nums[i] + 2 = nums[i+1])
We need to record one number. nums[i]+1.
------------------------------------------------------------------------------------------------
case 3: the gap's length is larger than 1. (nums[i] + 2 < nums[i+1])
We need to record the range. [nums[i]+1, nums[i+1]-1].


Write in this way is a little ugly, what's more we have lower and upper must be included. we could use two variables for this purpose: (to compute the gap between nums[i-1] and nums[i])
------------------------------------------------------------------------------------------------
after: the number after nums[i-1]
pre: the number before nums[i]
------------------------------------------------------------------------------------------------
if (pre == after) 
    ret.add(pre + "");
else if (pre > after)
    ret.add(after + "->" + pre);
after = nums[i] + 1;

Skill:
To involve the lower and upper, we could assign "after" with "lower" before scanning the nums. And assign "pre" with "upper" after the scan. 

int after = lower;
int pre;
for (int i = 0; i < nums.length; i++) {
...
}
pre = upper;
if (pre == after) 
    ret.add(pre + "");
else if (pre > after)
    ret.add(after + "->" + pre);

Wrong Solution:

public class Solution {
    public List<String> findMissingRanges(int[] nums, int lower, int upper) {
        if (nums == null)
            throw new IllegalArgumentException("nums is null");
        List<String> ret = new ArrayList<String> ();
        if (nums.length == 0) {
            String temp = lower + "->" + upper;
            ret.add(temp);
            return ret;
        }
        int after = lower;
        int pre;
        for (int i = 0; i < nums.length; i++) {
            pre = nums[i] - 1;
            if (pre == after) 
                ret.add(pre + "");
            else if (pre > after)
                ret.add(after + "->" + pre);
            after = nums[i] + 1;
        }
        pre = upper;
        if (pre == after) 
            ret.add(pre + "");
        else if (pre > after)
            ret.add(after + "->" + pre);
        return ret;
    }
}

Mistake Analysis:

Error case:
[], 1, 1
Output:
["1->1"]
Expected:
["1"]

Mistake analysis:
I have failed to consdier the corner case when nums.length = 0, and lower and upper share the same value.
Thus we should not use "->".
Fix:
if (lower < upper) {
    String temp = lower + "->" + upper;
    ret.add(temp);
} else{
    ret.add(lower + "");
}
Lesson: when the output should be genereated for different format (like "num1",  "num1 -> num2"), you should be careful with you handling with corner case.

Solution:

public class Solution {
    public List<String> findMissingRanges(int[] nums, int lower, int upper) {
        if (nums == null)
            throw new IllegalArgumentException("nums is null");
        List<String> ret = new ArrayList<String> ();
        if (nums.length == 0) {
            if (lower < upper) {
                String temp = lower + "->" + upper;
                ret.add(temp);
            } else{
                ret.add(lower + "");
            }
            return ret;
        }
        int after = lower;
        int pre;
        for (int i = 0; i < nums.length; i++) {
            pre = nums[i] - 1;
            if (pre == after) 
                ret.add(pre + "");
            else if (pre > after)
                ret.add(after + "->" + pre);
            after = nums[i] + 1;
        }
        pre = upper;
        if (pre == after) 
            ret.add(pre + "");
        else if (pre > after)
            ret.add(after + "->" + pre);
        return ret;
    }
}

 

推荐阅读