1、二维数组中的查找:数组特性观察,时间复杂度把握
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数
针对这个问题,我们首先要明确一个观点,那就是查找的过程,实际是排除的过程,我们当然可以遍历一遍矩阵,如果矩阵中有整数和输入的数相同,就返回true;但是这样未免过于繁琐,所以呢,可以这样:
1、首先定位到矩阵的右上角或左下角的值(15或18)
2、拿15为例,如果这个值小于target,那么target肯定不在这一行中;如果大于target,那肯定不在这一列中,这样就可以排除一行或一列;如果相等则返回true。
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.size()<=0) return false;//先判定限制条件
int i=0;
int j=matrix[0].size()-1;
int b=matrix.size();
while(i<b&&j>=0){
if(target<matrix[i][j]){
j--;
}
else if(target>matrix[i][j]){
i++;
}
else return true;
}
return false;
}
};
2、旋转数组的最小数字:二分查找,临界条件
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
看到这个问题,比较暴力的一种解法就是直接遍历一遍,找到最小值即可;另一种思路就是利用二分查找的思想,选定中间值,缩小查找区间,可以把旋转后的数组分为两部分,第一部分是第一个递增数组例如[3,4,5],第二部分是第二个递增数组,例如[1,2]:
1、定位数组最有左端l,最右端r,中间mid
2、如果a[mid]>=a[l],那么mid左边的数组还是递增的,说明mid位于第一部分数组,那么我们要找的最小值肯定在第二部分,则让l=mid;
3、如果a[mid]<a[l],那么最小值在mid左侧,让r=mid;
4、还有一种情况就是a[mid]=a[l]=a[r],这个时候就无法判断了,那么就直接在这个小范围内遍历
5、当r-l=1的时候,r就是我们要找的最小元素的位置
class Solution {
public:
int minArray(vector<int>& numbers) {
if(numbers.size()==0) return 0;
int l=0;
int r=numbers.size()-1;
int mid =0;
while (numbers[l]>=numbers[r])//循环条件,因为旋转后的数组,最左边比最右边的值要大或相等
{
if(r-l==1){
mid = r;
break;
}
//mid=(l+r)/2;
mid = l + ((r - l) >> 1);
//存在三者相等的情况导致无法判定
if(numbers[l]==numbers[mid]&&numbers[l]==numbers[r]){
int result=numbers[l];
for(int i=l+1;i<r;i++){
if(numbers[i]<result){
result=numbers[i];
}
}
return result;
}
if(numbers[mid]>=numbers[l]){
l=mid;
}
if(numbers[mid]<numbers[l]){
r=mid;
}
}
return numbers[mid];
}
};
3、按奇偶排序数组:数组操作,排序思想拓展应用
给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。
你可以返回满足此条件的任何数组作为答案。(我在这保证奇偶相对位置不变)
看到这个题,其实我脑海中有很多想法,如果不考虑顺序的话,我们可以用两个数组分别存储奇偶数等等;如果考虑顺序的话:
1、找到第一个偶数
2、它前面的所有奇数向后移动一个位置
3、按照这个方式遍历完整个数组
class Solution {
public:
vector<int> sortArrayByParity(vector<int>& A) {
int k=0;
for(int i=0;i<A.size();i++){
if(!(A[i]&1)){
int temp=A[i];
int j=i;
while(j>k){
A[j]=A[j-1];
j--;
}
A[k++]=temp;
}
}
return A;
}
};
4、替换空格:字符串相关,特性观察,临界条件处理
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
首先统计空格个数count,然后一个空格到“%20”内存+2,所以这个字符串要增加两个位置,然后倒序遍历一下即可
class Solution {
public:
string replaceSpace(string s) {
int l1 = s.length() - 1;
for (int i = 0; i <= l1; i++) {
if (s[i] == ' ') {
s += "00";
}
}
int l2 = s.length() - 1;
if (l2 <= l1) {
return s;
}
for (int i = l1; i >= 0; i--) {
char c = s[i];
if (c == ' ') {
s[l2--] = '0';
s[l2--] = '2';
s[l2--] = '%';
} else {
s[l2--] = c;
}
}
return s;
}
};