LeetCode刷题笔记(二) --- 数组相关

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值