Binary Search - LeetCode

423 阅读1分钟

Q****540. Single Element in a Sorted Array

You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. Find this single element that appears only once.

Follow up: Your solution should run in O(log n) time and O(1) space.

Example 1:

Input: nums = [1,1,2,3,3,4,4,8,8]
Output: 2

Example 2:

Input: nums = [3,3,7,7,10,11,11]
Output: 10

Constraints:

  • 1 <= nums.length <= 10^5

  • 0 <= nums[i] <= 10^5

解法及注释

class Solution {
    public int singleNonDuplicate(int[] nums) {
        if(nums.length == 1)
            return nums[0];
        
        int left = 0, right = nums.length - 1;
        if(nums[left] != nums[left + 1])
            return nums[left];
        else if(nums[right] != nums[right - 1])
            return nums[right];
        
        while(left <= right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] != nums[mid - 1] && nums[mid] != nums[mid + 1])
                return nums[mid];
            else if(mid % 2 == 0 && nums[mid] == nums[mid + 1] ||
                   mid % 2 == 1 && nums[mid] == nums[mid - 1])
                left = mid + 1;
            else 
                right = mid - 1;  
        }
        return -1; 
        
    }
}

Q****153. Find Minimum in Rotated Sorted Array

Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:

  • [4,5,6,7,0,1,2] if it was rotated 4 times.
  • [0,1,2,4,5,6,7] if it was rotated 7 times.

Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]].

Given the sorted rotated array nums, return the minimum element of this array.

Example 1:

Input: nums = [3,4,5,1,2]
Output: 1
Explanation: The original array was [1,2,3,4,5] rotated 3 times.

Example 2:

Input: nums = [4,5,6,7,0,1,2]
Output: 0
Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.

Example 3:

Input: nums = [11,13,15,17]
Output: 11
Explanation: The original array was [11,13,15,17] and it was rotated 4 times. 

Constraints:

  • n == nums.length
  • 1 <= n <= 5000
  • -5000 <= nums[i] <= 5000
  • All the integers of nums are unique.
  • nums is sorted and rotated between 1 and n times.

解法及注释

class Solution {
    public int findMin(int[] nums) {
        if(nums.length == 1)
            return nums[0];
        
        int left = 0, right = nums.length - 1;
        
        //case 1: if there is no rotation
        if(nums[right] > nums[0])
            return nums[0];
        
        //case 2: rotation exists in the array
        while(left <= right) {
            int mid = left + (right - left)/2;
            if(nums[mid] > nums[mid + 1]) 
                return nums[mid + 1];
            if(nums[mid - 1] > nums[mid]) {
                return nums[mid];
            }
            
            if(nums[mid] > nums[0]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }
}

Q****154. Find Minimum in Rotated Sorted Array II

Suppose an array sorted in ascending order 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.

Example 1:

Input: [1,3,5]
Output: 1

Example 2:

Input: [2,2,2,0,1]
Output: 0

Note:

解法及注释

class Solution {
    public int findMin(int[] nums) {
        if(nums.length == 1)
            return nums[0];
        
        int left = 0, right = nums.length - 1;
        
        while(left < right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] < nums[right])
                right = mid;
            else if(nums[mid] > nums[right])
                left = mid + 1;
            else if(nums[left] < nums[right])
                return nums[left];
            else {
                left++;
            }
        }
        return nums[left];
    }
}

Q****74. 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.

Example 1:

Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
Output: true

Example 2:

Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
Output: false

Constraints:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 100
  • -104 <= matrix[i][j], target <= 104

解法及注释

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int i = 0, j = matrix[0].length - 1;
        
        while(i >=0 && i < matrix.length && j >=0 && j < matrix[0].length) {
            if(matrix[i][j] == target)
                return true;
            else if(matrix[i][j] > target) {
                j--;
            } else if(matrix[i][j] < target) {
                i++;
            }
        }
        return false;
    }
}

Q****240. Search a 2D Matrix II

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

  • Integers in each row are sorted in ascending from left to right.
  • Integers in each column are sorted in ascending from top to bottom.

Example 1:

Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
Output: true

Example 2:

Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
Output: false

Constraints:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= n, m <= 300
  • -109 <= matix[i][j] <= 109
  • All the integers in each row are sorted in ascending order.
  • All the integers in each column are sorted in ascending order.
  • -109 <= target <= 109

解法及注释

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length == 1 && matrix[0].length == 1)
            return matrix[0][0] == target;
        
        int row = matrix[0].length, col = matrix.length;
        for(int i = 0; i < col; i++) {
            if(matrix[i][0] <= target && matrix[i][row - 1] >= target) {
               for(int j = 0; j < row; j++) {
                   if(matrix[i][j] == target)
                       return true;
               }
            } else 
                continue;
        }
        return false;
        
    }
}

Q****378. Kth Smallest Element in a Sorted Matrix

Given an n x n matrix where each of the rows and columns are sorted in ascending order, return the kth smallest element in the matrix.

Note that it is the kth smallest element in the sorted order, not the kth distinct element.

Example 1:

Input: matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
Output: 13
Explanation: The elements in the matrix are [1,5,9,10,11,12,13,13,15], 
and the 8th largest number is 13

Example 2:

Input: matrix = [[-5]], k = 1
Output: -5

Constraints:

  • n == matrix.length
  • n == matrix[i].length
  • 1 <= n <= 300
  • -109 <= matrix[i][j] <= -109
  • All the rows and columns of matrix are guaranteed to be sorted in non-degreasing order.
  • 1 <= k <= n2

解法及注释

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        if(matrix == null || matrix.length == 0)
            return -1;
        
        if(k > matrix.length * matrix[0].length)
            return -1; 
        
        PriorityQueue<Element> queue = new PriorityQueue<Element>((Element a, Element b) -> (a.val - b.val));
        
        
        for(int i = 0; i < matrix.length; i++) {
            Element element = new Element(matrix[i][0], 0, i);
            queue.add(element);
        }
        
        while(!queue.isEmpty() && k > 0) {
            Element e = queue.peek();
            queue.remove(e);
            k--;
            
            if(k == 0)
                return e.val;
            
            if(e.currIdx < matrix[e.rowIdx].length - 1) {
                e.currIdx += 1;
                e.val = matrix[e.rowIdx][e.currIdx];
                queue.add(e);
            }
        }
        return -1;
    }    
}

class Element {
    int val;
    int currIdx;
    int rowIdx;
    
    public Element(int val, int currIdx, int rowIdx) {
        this.val = val;
        this.currIdx = currIdx;
        this.rowIdx = rowIdx;
    }
}