zoukankan      html  css  js  c++  java
  • [LeetCode#240] Search a 2D Matrix II

    Problem:

    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 in ascending from left to right.
    • Integers in each column are sorted in ascending from top to bottom.

    For example,

    Consider the following 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]
    ]
    

    Given target = 5, return true.

    Given target = 20, return false.

    Analysis 1:

    This problem is still very easy, but it reminds me to repick up some skills I have abandoned for a long time.
    Instant idea:
    Since each column and row is sorted, we can take advantage of one of them. Go through each row one by one, for each row, we perform binary search. 
    Note: pitfall in binary search.
    1. wrong stop condition.
    while (left < right) 
    Input:
    [[-5]], -5
    Output:
    false
    Expected:
    true
    
    start: left = 0, right = 0
    not able to enter the loop, not able to reach
    int mid = (left + right) / 2;
    if (nums[mid] == target)
        return true;
    Fix: while (left <= right)
    
    2. wrong policy in update left and right pointer.
    if (nums[mid] == target)
        return true;
    else if(nums[mid] > target) {
        right = mid;
    } else {
        left = mid;
    }
    
    Input:
    [[-1,3]], 1
    start: left = 0, right = 1, 
    enter loop: mid = 0;
    nums[mid] < target
        left = mid = 0.
    No updates at all, would lead to infinite loop.
    Binary search is very important, you must remember the coding structure clearly.
    Time Complexity: O(nlogn)

    Solution 1:

    public class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            if (matrix == null)
                throw new IllegalArgumentException("the reference of the matrix is null");
            if (matrix.length == 0 || matrix[0].length == 0)
                return false;
            for (int i = 0; i < matrix.length; i++) {
                if (binarySearch(matrix[i], target))
                    return true;
            }
            return false;
        }
        
        
        private boolean binarySearch(int[] nums, int target) {
            if (nums[0] > target || target > nums[nums.length-1])
                return false;
            int left = 0;
            int right = nums.length - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                if (nums[mid] == target)
                    return true;
                else if(nums[mid] > target) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            return false;
        }
    }

    Analysis 2:

    Even though we have take advantage of sorted property of each row, how about each column?
    Can we also take advantage of it? so as to reduce time complexity. 
    
    Sure!!!
    Great idea:
    Start from up-right-most corner, then use the two sorted properties to exclude elements. 
    principle:
    1. iff matrix[x][y] > target, 
    since y is sorted, target must not able to appear on y column, we should skip it. 
    while ( y >= 1 && target < matrix[x][y] ) {
        y--;
    }   
    
    2. iff matrix[x][y] < target.
    since matrix[x][y-1] must smaller than it, and matrix[x][y+1] is impossilbe. (we have done in the previous step)
    the only possible direction is below. 
    
    Use this invariant, if the target exist in the matrix, we must be able to find it.
    for (int x = 0; x < matrix.length; x++) {
        while ( y >= 1 && target < matrix[x][y] ) {
            y--;
        }   
        if (matrix[x][y] == target)
        return true;
    }

    Soltuion 2:

    public class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
            if (matrix == null)
                throw new IllegalArgumentException("the reference of the matrix is null");
            if (matrix.length == 0 || matrix[0].length == 0)
                return false;
            int y = matrix[0].length-1;
            for (int x = 0; x < matrix.length; x++) {
                while ( y >= 1 && target < matrix[x][y] ) {
                    y--;
                }   
                if (matrix[x][y] == target)
                    return true;
            }
            return false;
        }
    }
  • 相关阅读:
    操作系统:DOS
    袁氏-人物:袁淑
    移植linux-2.6.32.2到qq2440
    qq2440启动linux后出现错误提示request_module: runaway loop modprobe binfmt-464c
    qq2440启动linux后插入u盘出现usb 1-1: device descriptor read/64, error -110,usb 1-1: device not accepting address 8, error -110
    ubuntu14.04 64bit安装teamviewer
    vi 的使用
    添加了环境变量,然而交叉编译器还是无法运行的解决方案
    linux下route命令使用实战
    ubuntu14.04纯命令行下连接有线网和无线网
  • 原文地址:https://www.cnblogs.com/airwindow/p/4777076.html
Copyright © 2011-2022 走看看