Timo66

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Binary search in sorted Array

Question 1

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)).
Refer to this link below:
http://www.cnblogs.com/springfor/p/3861890.html
 1 public class Solution {
 2     public double findMedianSortedArrays(int[] nums1, int[] nums2) {
 3         if (nums1 == null || nums2 == null)
 4             return 0;
 5         int m = nums1.length;
 6         int n = nums2.length;
 7         int k = (m+n)/2;
 8         
 9         if ((m+n) % 2 == 0){
10             double first = findMedianSortedArrays(nums1,0,m-1,nums2,0,n-1,k);
11             double second = findMedianSortedArrays(nums1,0,m-1,nums2,0,n-1,k+1);
12             return (first+second)/2;
13         }
14         else
15             return findMedianSortedArrays(nums1,0,m-1,nums2,0,n-1,k+1);
16     }
17     
18     public double findMedianSortedArrays(int[] A, int sA, int eA, int[] B, int sB, int eB, int k){
19         int m = eA - sA + 1;
20         int n = eB - sB + 1;
21         if (m > n)
22             return findMedianSortedArrays(B, sB, eB, A, sA, eA, k);
23         if (m == 0)
24             return B[k-1];
25         if (k == 1)
26             return Math.min(A[sA], B[sB]);
27         int partA = Math.min(k/2, m);
28         int partB = k - partA;
29         if (A[sA + partA-1] < B[sB + partB - 1])
30             return findMedianSortedArrays(A, sA + partA, eA, B, sB, eB, k-partA);
31         else if (A[sA + partA-1] > B[sB + partB - 1])
32             return findMedianSortedArrays(A, sA, eA, B, sB+partB, eB, k-partB);
33         else
34             return A[sA + partA - 1];
35     }
36 }

 

Search a 2D Matrix

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

 

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

 

For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

Given target = 3, return true.


row and colum's product -1 is the total number of this values. And a trick here is mid/colum is the row and mid%colum is the column.

public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length < 1)
            return false;
        
        int left = 0;
        int right = matrix.length * matrix[0].length - 1;
        
        while (left <= right){
            int mid = (left + right)/2;
            int value = matrix[mid/matrix[0].length][mid % matrix[0].length];
            if (value == target){
                return true;
            }
            else if (value < target){
                left = mid + 1;
            }
            else {
                right = mid - 1;
            }
        }
        return false;
    }

This is my initial solution, using two loops, more complex but more directly.

 1 public boolean searchMatrix(int[][] matrix, int target) {
 2         if (matrix == null)
 3             return false;
 4             
 5         if (matrix[0][0] > target)
 6             return false;
 7         int row_mid;
 8         int col_mid;
 9         int row_start = 0;
10         int col_start = 0;
11         int row_end = matrix.length-1;
12         int col_end = matrix[0].length-1;
13         
14         while (row_start <= row_end){
15             row_mid = (row_start + row_end)/2;
16             // matrix[row_mid][] is the one we are interested in
17             if (matrix[row_mid][0] == target){
18                 return true;
19             }
20             else if (matrix[row_mid][0] > target){
21                 row_end = row_mid - 1; 
22             }
23             else {
24                 row_start = row_mid + 1;
25             }
26         }
27         
28         row_mid = row_end;
29         if (row_mid < 0)
30             return false;
31             
32         while (col_start <= col_end){
33             col_mid = (col_start + col_end)/2;
34             int value = matrix[row_mid][col_mid];
35             if (value == target){
36                 return true;
37             }
38             else if (value < target){
39                 col_start = col_mid + 1;
40             }
41             else{
42                 col_end = col_mid - 1;
43             }
44         }
45             
46         return false;
47     }

Question 2

Search in Rotated Sorted Array

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

I use a hashmap tp record the index of each value in the array. Then I sort the array again and use binary search to find the value.

 1 public int search(int[] nums, int target) {
 2         if (nums == null || nums.length < 1)
 3             return -1;
 4         HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
 5         for (int i = 0; i < nums.length; i ++){
 6             map.put(nums[i], i);
 7         }
 8         Arrays.sort(nums);
 9         int start = 0;
10         int end = nums.length - 1;
11         int mid;
12         while (start <= end){
13             mid = (start + end) / 2;
14             if (nums[mid] == target){
15                 return map.get(nums[mid]);
16             }
17             else if (nums[mid] < target){
18                 start = mid + 1;
19             }
20             else{
21                 end = mid - 1;
22             }
23         }
24         return -1;
25     }

This method only use the iterative not hash map. But you always need to compare the nums[left] and nums[mid] relations.  

 1 public int search(int[] nums, int target) {
 2         if (nums == null || nums.length < 1)
 3             return -1;
 4         int left = 0;
 5         int right = nums.length - 1;
 6         int mid;
 7         while (left <= right){
 8             mid = (left + right)/2;
 9             if (nums[mid] == target){
10                 return mid;
11             }
12             if (nums[left] <= nums[mid]){
13                 if (nums[left] <= target && nums[mid] > target){
14                     right = mid - 1;
15                 }
16                 else{
17                     left = mid + 1;
18                 }
19             }
20             else if (nums[left] >= nums[mid]){
21                 if (nums[mid] < target && nums[right] >= target){
22                     left = mid + 1;
23                 }
24                 else{
25                     right = mid - 1;
26                 }
27             }
28         }
29         return -1;
30     }

Question 3

Search in Rotated Sorted Array II

Follow up for "Search in Rotated Sorted Array":

What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Write a function to determine if a given target is in the array.

I use iterative method here. Remember to add the method to check if there is duplicate. If the nums[left] == nums[mid] then if nums[mid] != nums[right], left directly change to mid + 1, else left ++;

 1 public boolean search(int[] nums, int target) {
 2         if (nums == null || nums.length < 1)
 3             return false;
 4         int left = 0;
 5         int right = nums.length - 1;
 6         int mid;
 7         
 8         while (left <= right){
 9             mid = (right + left)/2;
10             if (nums[mid] == target){
11                 return true;
12             }
13             else if (nums[left] > nums[mid]){
14                 if (nums[mid] < target && nums[right] >= target){
15                     left = mid + 1;
16                 }
17                 else{
18                     right = mid - 1;
19                 }
20             }
21             else if (nums[left] < nums[mid]){
22                 if (nums[left] <= target && nums[mid] > target){
23                     right = mid - 1;
24                 }
25                 else{
26                     left = mid + 1;
27                 }
28             }
29             else{
30                 if (nums[mid] != nums[right]){
31                     left = mid + 1;
32                 }
33                 else left ++;
34             } 
35         }
36         return false;
37     }

 

Question 4

Find Minimum in Rotated Sorted Array

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.

If left < right, then means it is a sorted array, and left is the minimum value and should be returned. And if mid < right, then we don't need to consider the value from mid to right; so we make right = mid. And if mid > right and before left > right, then mid to right has the minimum value;

 

 1 public int findMin(int[] nums) {
 2         if (nums == null || nums.length < 1){
 3             return Integer.MAX_VALUE;
 4         }
 5         int left = 0;
 6         int right = nums.length - 1;
 7         int mid;
 8         
 9         while (left != right){
10             if (nums[left] <= nums[right])
11                 return nums[left];
12             
13             mid = (left + right)/2;
14             
15             if (nums[mid] < nums[right])
16                 right = mid;
17             else
18                 left = mid + 1;
19         }
20         return nums[left];
21     }

 

 

 

Find Minimum in Rotated Sorted Array II

Follow up for "Find Minimum in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

The array may contain duplicates.

 This problem actually has the same solution as the above one. What is difference is that it may need O(n) complexity because of the duplication condition. If there are a lot of duplicate value, it will always run left++, then it will only need step by step working. 

 1     public int findMin(int[] num) {
 2         if(num == null || num.length==0)
 3             return 0;
 4         int l = 0;
 5         int r = num.length-1;
 6         int min = num[0];
 7         while(l<r-1)
 8         {
 9             int m = (l+r)/2;
10             if(num[l]<num[m])
11             {
12                 min = Math.min(num[l],min);
13                 l = m+1;
14             }
15             else if(num[l]>num[m])
16             {
17                 min = Math.min(num[m],min);
18                 r = m-1;
19             }
20             else
21             {
22                 l++;
23             }
24         }
25         min = Math.min(num[r],min);
26         min = Math.min(num[l],min);
27         return min;
28     }

 

 

 

posted on 2015-07-30 09:59  Timo66  阅读(281)  评论(0编辑  收藏  举报