Leetcode 240 Search a 2D Matrix II

在这里插入图片描述
思路一: 我自己的思路其实和appraoch 3是差不多的,都是将matrix分成四个部分(虽然我和lc分的四个部分不一样,但是不要紧,都是用来缩减search space的),用的也都是recursive的方法。但是approach3定位新的matrix是用left-up和right-bottom两个点坐标来重新定位的,而我是用4个函数重新构建新matrix的。很明显,lc的方法会更好一点。这也是为什么我tle的原因。我觉得我改一下,改成两点定位的话应该也能accpted。但是我今天实在太累了,不想改了。建议复盘的时候重改代码。具体思路的话去lc看approach3思路。下面展示下approach3代码以及我自己的代码:

// 自己的代码
class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length == 0) return false;
        if(matrix[0].length == 0) return false;
        int m = matrix.length;
        int n = matrix[0].length;
        if(target < matrix[0][0]) return false;
        if(target > matrix[m - 1][n - 1]) return false;
        int left = 0;
        int right = m * n - 1;
        int mid = left + (right - left) / 2;
        if(matrix[mid / n][mid % n] == target) return true;
        else if(matrix[mid / n][mid % n] > target){
            return searchMatrix(upMatrix(matrix,left,right),target) || searchMatrix(leftMatrix(matrix,left,right),target); 
        }else{
            return searchMatrix(downMatrix(matrix,left,right),target) || searchMatrix(rightMatrix(matrix,left,right),target); 
        }
    }
    
    private int[][] upMatrix(int[][] matrix, int left, int right){
        int n = matrix[0].length;
        int mid = left + (right - left) / 2;
        int row = mid / n;
        int[][] res = new int[row][n];
        for(int i = 0; i < row; i++){
            for(int j = 0; j < n; j++){
                res[i][j] = matrix[i][j];
            }
        }
        return res;
    }
    
    private int[][] downMatrix(int[][] matrix, int left, int right){
        int m = matrix.length;
        int n = matrix[0].length;
        int mid = left + (right - left) / 2;
        int row = mid / n;
        int[][] res = new int[m - 1 - row][n];
        for(int i = row + 1; i < m ; i++){
            for(int j = 0; j < n; j++){
                res[i-1-row][j] = matrix[i][j];
            }
        }
        return res;
    }
    
    private int[][] leftMatrix(int[][] matrix, int left, int right){
        int m = matrix.length;
        int n = matrix[0].length;
        int mid = left + (right - left) / 2;
        int col = mid % n;
        int[][] res = new int[m][col];
        for(int i = 0; i < m ; i++){
            for(int j = 0; j < col; j++){
                res[i][j] = matrix[i][j];
            }
        }
        return res;
    }
    
    private int[][] rightMatrix(int[][] matrix, int left, int right){
        int m = matrix.length;
        int n = matrix[0].length;
        int mid = left + (right - left) / 2;
        int col = mid % n;
        int[][] res = new int[m][n - 1 - col];
        for(int i = 0; i < m ; i++){
            for(int j = col + 1; j < n; j++){
                res[i][j - col - 1] = matrix[i][j];
            }
        }
        return res;
    }
}
// lc的代码
class Solution {
    private int[][] matrix;
    private int target;

    private boolean searchRec(int left, int up, int right, int down) {
        // this submatrix has no height or no width.
        if (left > right || up > down) {
            return false;
        // `target` is already larger than the largest element or smaller
        // than the smallest element in this submatrix.
        } else if (target < matrix[up][left] || target > matrix[down][right]) {
            return false;
        }

        int mid = left + (right-left)/2;

        // Locate `row` such that matrix[row-1][mid] < target < matrix[row][mid]
        int row = up;
        while (row <= down && matrix[row][mid] <= target) {
            if (matrix[row][mid] == target) {
                return true;
            }
            row++;
        }

        return searchRec(left, row, mid-1, down) || searchRec(mid+1, up, right, row-1);
    }

    public boolean searchMatrix(int[][] mat, int targ) {
        // cache input values in object to avoid passing them unnecessarily
        // to `searchRec`
        matrix = mat;
        target = targ;

        // an empty matrix obviously does not contain `target`
        if (matrix == null || matrix.length == 0) {
            return false;
        }

        return searchRec(0, 0, matrix[0].length-1, matrix.length-1);
    }
}

思路二: lc Approach 4: Search Space Reduction。这个方法很巧妙,建议直接看lc solution approach 4思路。思路其实真的挺简单的,只不过很难自己想到,下次记住就好了。我自己没有实现代码,复盘的时候建议自己实现一下。这边我直接展示lc代码:

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        // start our "pointer" in the bottom-left
        int row = matrix.length-1;
        int col = 0;

        while (row >= 0 && col < matrix[0].length) {
            if (matrix[row][col] > target) {
                row--;
            } else if (matrix[row][col] < target) {
                col++;
            } else { // found it
                return true;
            }
        }

        return false;
    }
}

总结:

  1. approach 3 Divide and Conquer这个方法要去多了解,好像目前为止碰到两三次了。
  2. 这题还有binary search的解法,我看了会儿没看懂,没有耐心了,但是感觉还挺重要的,复盘的时候建议重新看一下approach 2 binary search。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值