剑指offer第1题:二维数组中的查找

题目表述

二维数组中的查找:

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如:
1 5 10 15 20 2 6 11 16 21 3 7 12 17 22 4 8 13 18 23 \begin{matrix} 1 & 5 & 10 & 15 & 20\\ 2 & 6 & 11 & 16 & 21 \\ 3& 7 & 12 & 17 & 22 \\ 4 & 8 & 13 & 18 & 23 \end{matrix} 12345678101112131516171820212223
目标数:12.返回值为:True.

分析

思路一:直接遍历

遍历二维数组中的每个元素,直到找到该整数或者遍历完。

思路二:利用有序性特点

在思路一的基础上,从左上角开始,按照从左向右遍历,若找到返回True,若遇到比它大的数,记录此时的列号row,说明凡是列号大于等于row的数都是大于target的,那么下次搜索时,列号的范围就是从0到row-1,遍历中如遇到比它大的数,就进一步更换列号上限,直到遍历完或者找到目标。

思路三:利用较大数排除列,利用较小数排除行

在思路二,我们发现当遇到一个比Target大的数B时,那么由于矩阵的有序行,就直接排除了数B右侧(且行号不小于B的行号)的所有数。类似的,可以发现,当一个数S小于Target时,我们可以排除与S所在行中左侧及自身的所有数。
所以,从矩阵的右上角来开始搜索:
由于20>12,故排除20所在列,剩下的矩阵为:
1 5 10 15 2 6 11 16 3 7 12 17 4 8 13 18 \begin{matrix} 1 & 5 & 10 & 15 \\ 2 & 6 & 11 & 16 \\ 3& 7 & 12 & 17 \\ 4 & 8 & 13 & 18 \end{matrix} 123456781011121315161718
继续,由于15>12,故排除15所在列,剩下的矩阵为:
1 5 10 2 6 11 3 7 12 4 8 13 \begin{matrix} 1 & 5 & 10 \\ 2 & 6 & 11 \\ 3& 7 & 12 \\ 4 & 8 & 13 \end{matrix} 1234567810111213
继续,由于10<12,故排除10所在行,剩下的矩阵为:
2 6 11 3 7 12 4 8 13 \begin{matrix} 2 &amp; 6 &amp; 11 \\ 3&amp; 7 &amp; 12 \\ 4 &amp; 8 &amp; 13 \end{matrix} 234678111213
继续,由于11<12,故排除11所在行,剩下的矩阵为:
3 7 12 4 8 13 \begin{matrix} 3&amp; 7 &amp; 12 \\ 4 &amp; 8 &amp; 13 \end{matrix} 34781213
此时 ,所剩矩阵的右上角数字为12等于target,返回TRUE.

比较分析:思路一需要遍历所有元素,时间复杂度为O(mn),思路二,依然要逐行遍历,若Target在矩阵右下角,则仍然需要遍历整个矩阵,时间复杂度仍为o(mn),思路三,每次都可以排除整行或者整列,故时间复杂度为O(N),N =max(m,n)。

源码

class Solution {
	public:
    bool Find(int target, vector<vector<int> > array) {
       if(array.empty()) return false;
       int rows = array.size();
       int clos = array[0].size();
       int i = 0;
       int j = clos-1;//从右上角开始
       while(i<rows && j>=0)
       {
           if(array[i][j]== target) return true;
           if(array[i][j] < target) i++;
           else j--;
       }
        return false;
    }
};
class Solution {
public:
	void replaceSpace(char *str,int length) {
//遍历找到新串的长度;
        int L = 0;
        for(int i = 0;i<length;i++)
        {
            if(str[i]==' ') L++; 
        }
        L = L*2+length;
        //
        int l = length-1;
        int r = L -1;
        while(l>=0)
        {
            if(str[l]==' ')
            {
                str[r--]='0';
                str[r--]='2';
                str[r]='%';
            }
            else
            {
                str[r]=str[l]; 
            }
            r--;
            l--;
 }
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值