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;
        }
    };
    
  • 相关阅读:
    Spring编译AOP项目报错
    Intellij新建Spring项目引入用户目录下的Spring jar包
    python如何安装第三方库
    sizeof and strlen整理
    数轴上从左到右有n个点a[0],a[1]…,a[n-1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点。要求算法复杂度为o(n)。
    百度笔试题--最长回文字串
    微软笔试题
    人群智商差不多,是什么引起了差距?
    低层次“努力学习”和学习的本质
    集成 solr6.5.1到 tomcat7(8) 中 (解决java.lang.NoSuchMethodError问题)
  • 原文地址:https://www.cnblogs.com/Bylight/p/10440681.html
Copyright © 2011-2022 走看看