Problem:
Given a sorted integer array where the range of elements are [lower, upper] 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; } }
原文:http://www.cnblogs.com/airwindow/p/4796742.html