题目表述
二维数组中的查找:
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如:
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 & 6 & 11 \\ 3& 7 & 12 \\ 4 & 8 & 13 \end{matrix}
234678111213
继续,由于11<12,故排除11所在行,剩下的矩阵为:
3
7
12
4
8
13
\begin{matrix} 3& 7 & 12 \\ 4 & 8 & 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--;
}
}
};