数据结构算法之二分搜索查找多位矩阵中的数据

74. 搜索二维矩阵

在一个m*n维矩阵中搜索某一个给定值,如果存在则返回true,如果不存在则返回 false

一次二分法使用

解题想法,根据前面 33题的解题思路,使用搜索算法,先计算数组的行数m和n
得到起始位 start = 0
终止位 end = m*n - 1
中间位 mid = start + ((end-start)>>1)

  • 判断当前值处于那个区间
    • 取出数组的开始和末尾两个数
      • 比较中位数与目标值之间的差距(如果处于 start-》mid 区间,处于mid-end区间)
      • 逐渐逼近目标值
/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function(matrix, target) {
    if(!matrix||matrix.length<1){
        return false;
    }
    let m = matrix.length, n = matrix[0].length;

    let start = 0, end = matrix.length-1;
    while(start<=end){
        // let front = matrix[mid][0];
        // let back = matrix[end][n-1];

        let mid = start + ((end-start)>>1);
        if(matrix[mid][0]<target){
            start = mid+1;
        }

        if(matrix[mid][0]>target){
            end = mid-1;
        }

        if(matrix[mid][0]==target){
            return true;
        }

        if(matrix[mid][0]<=target&&matrix[mid][n-1]>=target){
            for(let i=0;i<matrix[mid].length;i++){
                if(matrix[mid][i]==target){
                    return true;
                }
            }
        }

    }
    return false;
};
结果

执行用时: 80 ms , 在所有 JavaScript 提交中击败了 19.44% 的用户
内存消耗: 38.8 MB, 在所有 JavaScript 提交中击败了 40.36% 的用户
通过测试用例:133 / 133

复杂度分析
- 时间复杂度 第一层二分法,第二层遍历 O(n*log(m))
- 空间复杂度 O(1)
两次二分法改进

由于使用了二分法 那么在二次搜索的时候 同样可以使用二分法 提高效率

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function(matrix, target) {
    if(!matrix||matrix.length<1){
        return false;
    }
    // let m = matrix.length;
    let n = matrix[0].length;

    let start = 0, end = matrix.length-1;
    while(start<=end){
        // let front = matrix[mid][0];
        // let back = matrix[end][n-1];

        let mid = start + ((end-start)>>1);
        if(matrix[mid][0]<target){
            start = mid+1;
        }

        if(matrix[mid][0]>target){
            end = mid-1;
        }

        if(matrix[mid][0]==target){
            return true;
        }

        if(matrix[mid][0]<=target&&matrix[mid][n-1]>=target){
            //let startInner = 0, endInner = n-1;
            return search(matrix[mid],target);
            // for(let i=0;i<matrix[mid].length;i++){
            //     if(matrix[mid][i]==target){
            //         return true;
            //     }
            // }
        }

    }
    return false;
};

var search = function(nums,target){
    let start = 0,end = nums.length-1,mid=0;
    while(start<=end){
        mid = start + ((end-start)>>1); //防止位溢出
        if(nums[mid]==target){
            return true;
        }

        if(nums[mid]<target){
            start = mid+1;
        }

        if(nums[mid]>target){
            end = mid-1;
        }
    }
    return false;
}

执行结果: 通过

结果

执行用时: 56 ms , 在所有 JavaScript 提交中击败了 99.30%的用户
内存消耗: 39 MB , 在所有 JavaScript 提交中击败了 18.64%的用户
通过测试用例: 133 / 133

复杂度分析
- 时间复杂度 第一层二分法,第二层二分法 O(log(n)*log(m))
- 空间复杂度 O(1)
优化变量使用

在前面的程序中,出现了一个中间变量,在下面等程序中减少了,速度减少了,但是空间利用率上去了,综合起来下面这种方式可能更好吧

 var searchMatrix = function(matrix, target) {
    if(!matrix||matrix.length<1){
        return false;
    }
    // let m = matrix.length;
    // let n = matrix[0].length;

    let start = 0, end = matrix.length-1;
    while(start<=end){
        // let front = matrix[mid][0];
        // let back = matrix[end][n-1];

        let mid = start + ((end-start)>>1);
        if(matrix[mid][0]<target){
            start = mid+1;
        }

        if(matrix[mid][0]>target){
            end = mid-1;
        }

        // 只有一层和一个值的时候
        if(matrix[mid][0]==target){
            return true;
        }

        // 满足大于等于和小于等于的情况要考虑 一层 但是有多个数字
        if(matrix[mid][0]<=target&&matrix[mid][matrix[0].length-1]>=target){
            //let startInner = 0, endInner = n-1;
            return search(matrix[mid],target);
            // for(let i=0;i<matrix[mid].length;i++){
            //     if(matrix[mid][i]==target){
            //         return true;
            //     }
            // }
        }

    }
    return false;
};

var search = function(nums,target){
    let start = 0,end = nums.length-1,mid=0;
    while(start<=end){
        mid = start + ((end-start)>>1); //防止位溢出
        if(nums[mid]==target){
            return true;
        }

        if(nums[mid]<target){
            start = mid+1;
        }

        if(nums[mid]>target){
            end = mid-1;
        }
    }
    return false;
}
结果

执行结果: 通过

执行用时: 64 ms , 在所有 JavaScript 提交中击败了 92.26% 的用户
内存消耗: 38.3 MB , 在所有 JavaScript 提交中击败了 67.01% 的用户
通过测试用例: 133 / 133

复杂度分析

未改变底层方法因此时间和空间复杂度同上

参考链接

74. 搜索二维矩阵

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法算法设计:研究如何将解决问题的步骤形式化为一系列指令,使得计算机可以执行以求解问题。 算法特性:包括输入、输出、有穷性、确定性和可行性。即一个有效的算法必须能在有限步骤内结束,并且对于给定的输入产生唯一的确定输出。 算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法,分支限界法等。 算法分析:通过数学方法分析算法的时间复杂度(运行时间随数据规模增长的速度)和空间复杂度(所需内存大小)来评估其效率。 学习算法数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值