4. Median of Two Sorted Arrays && 295. Find Median from Data Stream

4. Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5
 
Analyze:
array1, len m. cut i, i items on the left, (m-i) on the right.   
array2, len n. cut j, j items on the left, (n-j) on the right.
 
a[0],a[1],...,a[cut-1]  |  a[cut], a[cut+1], ... a[l-1]
 
Find cut i in [0,m], and cut j in [0,n] such that
 
a1[i-1]<=a2[j] && a1[j-1] <= a2[i]
 
If M+N is even:
i+j = m-i + n-j.  
Median = 0.5*(Math.max(a1[i-1], a2[j-1) + Math.min(a1[i], a2[j]));
If M+N is odd:
i+j+1 = m-i + n-j. (You can always convert to this)
Median = Math.min(a1[i], a2[j]);
 
j=(m+n)/2 - i;
 
public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int l1 = nums1.length;
        int l2 = nums2.length;
        int l = l1+l2;
        int s = l/2;
        int left = 0;
        int right = l1;
        
        while(left<=right)
        {
            int cut1 = (left+right)/2;
            int cut2 = s - cut1;
            //Make sure:  nums2[cut2-1] <= nums1[cut1]
            if(cut2 > l2 || cut2>0 && cut1<l1 && nums1[cut1]<nums2[cut2-1])
            {
                left = cut1+1;//This must move forward, otherwise, infinite loop.
                continue;
            }
            //Make sure:  nums1[cut1-1] <= nums2[cut2]
            if(cut2 < 0 || (cut1>0 && cut2<l2 && nums1[cut1-1]>nums2[cut2]))
            {
               right = cut1-1;//cut1 is guranteed to be less than right, so it has already moved forward.
               continue;
            }
            
            //if cut1 passes all previous checks, then it is the CUT!!!
            int rightMin = -1;
            if(cut1 == l1)
                rightMin = nums2[cut2];
            else if(cut2 == l2)
                rightMin = nums1[cut1];
            else
                rightMin = Math.min(nums1[cut1], nums2[cut2]);
            if(l%2 == 0)
            {
                int leftMax = -1;
                if(cut1 == 0)
                    leftMax = nums2[cut2-1];
                else if(cut2 == 0)
                    leftMax = nums1[cut1-1];
                else
                    leftMax = Math.max(nums1[cut1-1], nums2[cut2-1]);
            
                return 0.5*(leftMax+rightMin);
            }
            else
                return rightMin;
        }
        return -1;
    }
}

 

295. Find Median from Data Stream

Examples: 

[2,3,4] , the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

  • void addNum(int num) - Add a integer number from the data stream to the data structure.
  • double findMedian() - Return the median of all elements so far.

For example:

add(1)
add(2)
findMedian() -> 1.5
add(3) 
findMedian() -> 2
Idea:
Keep two priority queue. One for smaller half of the numbers, the other for larger half.
 
public class MedianFinder {
  private PriorityQueue<Integer> left = new PriorityQueue<>(1000, Collections.reverseOrder());
  private PriorityQueue<Integer> right = new PriorityQueue<>();

  //make sure left queue has equal length as or only one element longer than right queue
  public void addNum(int num) {
    left.offer(num); //merge num into left.
    right.offer(left.poll()); //move left's max to right
    if (left.size() < right.size())
      left.offer(right.poll());
  }

  // Returns the median of current data stream
  public double findMedian() {
    if (left.size() == right.size())
      return (left.peek() + right.peek()) / 2.0;
    else
      return left.peek();
  }
}

// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf = new MedianFinder();
// mf.addNum(1);
// mf.findMedian();

 

 

 

 

 
posted @ 2016-06-25 13:47  新一代的天皇巨星  阅读(190)  评论(0)    收藏  举报