zoukankan      html  css  js  c++  java
  • 剑指offer:二维数组中的查找

    题目

    题目链接
    剑指offer:二维数组中的查找
    题目描述
    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

    解题思路

    这题解题的关键在于数据是有序的,很自然的便想到使用二分法;在提交后在评论区发现了更优的解法(除了数据有序外,利用了数据按矩阵形式排列这一特点),会在下列代码中给出。
    在使用二分法时,值得注意的是,不能将二维数组中所有元素看作单调递增排列的一维数组,从而对所有元素整体进行二分。题目仅说明数据在矩阵的每行每列各自具单调递增的性质;而行(或列)之间并没有确定的大小关系。例如,第一行可能是[4, 5, 6], 而第二行为[1, 2, 3],第二行元素可能小于第一行元素。

    具体代码

    1. 二分法
    因为只能逐行进行二分,故算法时间复杂度为O(nlogm),n为矩阵行数,m为列数。
    计算二分的中值mid时,推荐使用mid = (right - left) / 2 + left而不是mid = (left + right) / 2 ,这样能够避免加法溢出

    class Solution {
    public:
        bool Find(int target, vector<vector<int> > array) {
            // 求出矩阵行数row和列数col
            int row = array.size();
            int col = array[0].size();
            
            int left;
            int right;
            int mid;
            // 对数组逐行进行二分查找
            for (int i = 0; i < row; i++) {
                left = 0;
                right = col - 1;
                while (right >= left) {
                    mid = (right - left) / 2 + left; // 防止left+right导致加法溢出
                    if (array[i][mid] < target) {
                        left = mid + 1;
                    } else if (array[i][mid] > target) {
                        right = mid - 1;
                    } else {
                        return true;
                    }
                }
            }
            
            return false;
        }
    };
    

    2. 利用元素特殊的排列
    利用元素排列的性质,对于左下角的元素来说,其同列上方的元素一定是小于它,其同行右方的元素一定是大于它;能够在推导的过程中跳过更多的错误元素。易知,算法时间复杂度为O(n+m)

    class Solution {
    public:
        bool Find(int target, vector<vector<int> > array) {
            // 求出矩阵行数row和列数col
            int row = array.size();
            int col = array[0].size();
            
            // 初始从矩阵左下方开始查找
            for (int i = row - 1, j = 0; i >= 0 && j < col; ) {
                // 分三种情况
                // 1. 当前位置元素大于目标位置元素,位置上移一行(i--)
                // 2. 当前位置元素小于目标位置元素,位置右移一列(j++)
                // 3. 当前位置元素等于目标位置元素,已找到,返回true
                if (target < array[i][j]) {
                    i--;
                } else if (target > array[i][j]) {
                    j++;
                } else {
                    return true;
                }
            }
            
            return false;
        }
    };
    
  • 相关阅读:
    关于跨域名访问,反向代理系列话题集锦
    中国B2C电子商务最新发展状况调查分析(转)
    顶部导航条(Top Navigation Bar)_Yahoo_Pattern(翻译)
    google,百度,yahoo,msn,ASK网址登录和网站地图提交地址
    如何安装PE到硬盘(包括移动硬盘)分区
    ASP.NET SQL 注入免费解决方案
    O2O循环圈
    B2C暴利行业之保健品行业
    在SQLserver2005中如何对运行慢的查询进行分析?
    互联网产品设计之需求管理
  • 原文地址:https://www.cnblogs.com/Bylight/p/10440681.html
Copyright © 2011-2022 走看看