leetcode200题之数组(一)

1.旋转图像

方法参考:https://leetcode-cn.com/problems/rotate-image/solution/li-kou-48xiao-bai-du-neng-kan-dong-de-fang-fa-zhu-/

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int pos1=0, pos2=matrix.size()-1;
        while(pos1<pos2){
            int add=0;  //偏移量
            while(pos1+add<pos2){
                int tmp=matrix[pos1][pos1+add];    
                matrix[pos1][pos1+add]=matrix[pos2-add][pos1];
                matrix[pos2-add][pos1]=matrix[pos2][pos2-add];
                matrix[pos2][pos2-add]=matrix[pos1+add][pos2];
                matrix[pos1+add][pos2]=tmp;
                add++;  //偏移量每轮加1,使得整行/整列完成旋转
            }
            pos1++;  //缩进到内一侧
            pos2--;
        }
    }
};

2. 除自己以外数组的乘积

思路:除自己以外乘积=自己(当前元素)的左侧乘积*自己的右侧乘积。

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int len=nums.size();
        vector<int> res(len,1);
        int L=1;
        for(int i=0; i<len; i++){
            res[i]=res[i]*L;
            L *= nums[i];
        }
        int R=1;
        for(int i=len-1; i>=0; i--){
            res[i]=res[i]*R;
            R *= nums[i];
        }
        return res;
    }
};

3.合并区间

  1. 对 vector<vector<int>> 排序,需要按照先比较区间开始,如果相同再比较区间结束,使用默认的排序规则即可
  2. 使用双指针,左边指针指向当前区间的开始
  3. 使用一个变量来记录连续的范围 t
  4. 右指针开始往后寻找,如果后续的区间的开始值比 t 还小,说明重复了,可以归并到一起,此时更新更大的结束值到 t,直到区间断开,将 t 作为区间结束,存储到答案里
  5. 然后移动左指针,跳过中间已经合并的区间
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());
        vector<vector<int>> res;
        for(int i=0; i<intervals.size();){
            int t=intervals[i][1];
            int j=i+1;
            while(j<intervals.size() && intervals[j][0]<=t){ //如果后续区间开始值比t小
                t = max(t, intervals[j][1]);  //更新最大的结束值  -> t
                j++;   
            }
            res.push_back({intervals[i][0],t});
            i=j;  //跳过已经合并的区间
        }
        return res;
    }
};

4.1比特与2比特字符

我们可以对 bits 数组从左到右扫描来判断最后一位是否为一比特字符。

当扫描到第 i 位时,如果 bits[i]=1,那么说明这是一个两比特字符,将 i 的值增加 2。如果 bits[i]=0,那么说明这是一个一比特字符,将 i 的值增加 1。

如果 i 最终落在了bits.size()−1 的位置,那么说明最后一位一定是一比特字符。

class Solution {
public:
    bool isOneBitCharacter(vector<int>& bits) {
        int i=0;
        while(i<bits.size()-1){
            i += bits[i] +1;
        }
        return i==bits.size()-1;
    }
};

5. 找到所有数组中消失的数字

  1. 遍历输入数组的每个元素一次。
  2. 我们将把 abs(nums[i])-1 索引位置的元素标记为负数。即 nums[abs(nums[i])−1]×−1 。
  3. 然后遍历数组,若当前数组元素 nums[i] 为负数,说明我们在数组中存在数字 i+1
class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        vector<int> res;
        for(int i=0; i<nums.size(); i++){
            if(nums[abs(nums[i])-1]>0){
                nums[abs(nums[i])-1] *= -1;
            }
        }
        for(int i=1; i<=nums.size(); i++){
            if(nums[i-1]>0){
                res.push_back(i);
            }
        }
        return res;
    }
};

6. 最短无须连续子数组

思路:有一定的单调栈思想。

  1. 一次扫描:找到无序子数组的最大最小元素
  2. 找到最小元素正确位置;
  3. 找到最大元素正确位置。
class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        int _max=INT_MIN, _min=INT_MAX;
        for(int i=0; i<nums.size()-1; i++){
            if(nums[i+1]<nums[i]){
                _min=min(_min, nums[i+1]);
                _max=max(_max, nums[i]);
            }
        }
        int l, r;
        for(l=0; l<nums.size(); l++){
            if(nums[l]>_min){
                break;
            }
        }
        for(r=nums.size()-1; r>=0; r--){
            if(nums[r]<_max){
                break;
            }
        }
        return r-l+1>0 ? r-l+1 : 0;

    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值