228. Summary Ranges && 163 Missing Ranges && 352. Data Stream as Disjoint Intervals

228. Summary Ranges

Given a sorted integer array without duplicates, return the summary of its ranges.

For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"].

 
public class Solution {
    public List<String> summaryRanges(int[] nums) {
        List<String> list=new ArrayList();
        if(nums.length==1){
            list.add(Integer.toString(nums[0]));
            return list;
        }
        for(int i=0;i<nums.length;i++){
            int begin=nums[i];
            //move i all the way to the end
            while(i+1<nums.length && (nums[i+1]-nums[i])==1)
                i++;
                
            if(begin!=nums[i])
                list.add(begin+"->"+nums[i]);
            else
                list.add(Integer.toString(begin));
        }
        return list;
    }
}

 

163 Missing Ranges

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"].

 

public List<String> findMissingRanges(int[] a, int lo, int hi) {
  List<String> res = new ArrayList<String>();
  
  // the next number we need to find
  int next = lo;
  
  for (int i = 0; i < a.length; i++) {
    // not within the range yet
    if (a[i] < next) continue;
    
    // continue to find the next one
    if (a[i] == next) {
      next++;
      continue;
    }
    
    // get the missing range string format
    res.add(getRange(next, a[i] - 1));
    
    // now we need to find the next number
    next = a[i] + 1;
  }
  
  // do a final check
  if (next <= hi) res.add(getRange(next, hi));

  return res;
}

String getRange(int n1, int n2) {
  return (n1 == n2) ? String.valueOf(n1) : String.format("%d->%d", n1, n2);
}

 

352. Data Stream as Disjoint Intervals

Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen so far as a list of disjoint intervals.

For example, suppose the integers from the data stream are 1, 3, 7, 2, 6, ..., then the summary will be:

[1, 1]
[1, 1], [3, 3]
[1, 1], [3, 3], [7, 7]
[1, 3], [7, 7]
[1, 3], [6, 7]

Follow up:
What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size?

 
/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class SummaryRanges {

TreeMap<Integer, Interval> tree;

  /** Initialize your data structure here. */
  public SummaryRanges() {
    //key is the start of the interval
    tree = new TreeMap<>();
  }

  public void addNum(int val) {
    if (tree.containsKey(val))
      return;

    Integer l = tree.lowerKey(val); // l -> [l, ?]
    Interval lInterval = null;
    if (l != null)
      lInterval = tree.get(l);  //this indicates val >= l

    Integer h = tree.higherKey(val); // h -> [h, ?]

    if (lInterval != null && h != null &&
      lInterval.end + 1 == val &&
      h == val + 1) {
      //merging two surrounding intervals
      lInterval.end = tree.get(h).end;
      tree.remove(h);
    } else { //only has interval at one end
      if (lInterval != null && lInterval.end + 1 >= val) {
        //merge with left interval
        lInterval.end = Math.max(lInterval.end, val);
      } else if (h != null && h == val + 1) {
        //update right interval
        tree.put(val, new Interval(val, tree.get(h).end));
        tree.remove(h);
      } else {
        tree.put(val, new Interval(val, val));
      }
    }
  }

  public List<Interval> getIntervals() {
    return new ArrayList<>(tree.values());
  }
}

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges obj = new SummaryRanges();
 * obj.addNum(val);
 * List<Interval> param_2 = obj.getIntervals();
 */

 

 

 

 

 

posted @ 2016-07-02 13:37  新一代的天皇巨星  阅读(167)  评论(0)    收藏  举报