leetcode真题——数组汇总: 27. 移除元素 977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II

文章目录

    • 27. 移除元素
    • 977. 有序数组的平方
    • 209. 长度最小的子数组
    • 59. 螺旋矩阵 II

27. 移除元素

leetcode真题——数组汇总: 27. 移除元素 977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II_第1张图片

https://leetcode-cn.com/problems/remove-element/
快慢指针,慢指针指向当前数组元素,快指针指找非val的元素给nums[slow]赋值

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow = 0;
        //只有在找到非val时当前数组的元素才更新
        for(int fast = 0; fast < nums.size(); fast++){
            if(nums[fast]!=val){
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
};

977. 有序数组的平方

https://leetcode-cn.com/problems/squares-of-a-sorted-array/
leetcode真题——数组汇总: 27. 移除元素 977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II_第2张图片
如果先把数组中元素都平方,在使用sort函数对其排序,那么时间复杂度为O(n*log n)

此题有个关键点就是平方前就是排好序的,那么平方后可能会出现负数的平方变大,而中间的数平方不可能比两边的平方大。所以先弄个和原来数组一样大的数组res,res从末尾开始赋值,比较nums两边的平方,将大的值赋给res,直到两边的指针 i j 相遇。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int k = nums.size() - 1;
        vector<int> res(nums.size(),0);
        for(int i = 0, j = nums.size() - 1 ; i <= j;){
            if(nums[i] * nums[i] > nums[j] * nums[j]){
                res[k--] = nums[i] * nums[i];
                i++;
            }else{
                res[k--] = nums[j] * nums[j];
                j--;
            }
        }
        return res;
    }
};

需要注意的是,vector如果没有初始化大小,那么只能使用.push_back(xx)来进行赋值,初始化后可以使用下标赋值。

209. 长度最小的子数组

https://leetcode-cn.com/problems/minimum-size-subarray-sum/
leetcode真题——数组汇总: 27. 移除元素 977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II_第3张图片
使用双指针算法记录一个区间窗口,保证窗口内元素和sum>=target,i 指向窗口左端,j 指向窗口右端,j不断右移累计sum,当 i j 之间的元素和 >= target 时说明此时窗口左区间需要右移,同时恢复sum值 即sum-=nums[i];i++.
初始化i=0,j=0,res = nums.size() + 1 (如果res更新过那么res一定<=size,所以将res的初值赋为size+1才能判断最后res有没有更新)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int res = nums.size() + 1 ;
        int i = 0, sum = 0;
        for(int j = 0; j < nums.size(); j++){
            sum += nums[j];
            while(sum >= target){
                res = res < j - i + 1? res : j - i + 1;  
                sum -= nums[i];
                i++;
            }
        }
        return (res == nums.size() + 1)? 0 : res;
    }
};

在这里插入图片描述

59. 螺旋矩阵 II

https://leetcode-cn.com/problems/spiral-matrix-ii/
leetcode真题——数组汇总: 27. 移除元素 977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II_第4张图片
在每一圈的循环中,都要处理四个边,每个边的赋值都遵循左闭右开的原则:

  • 左->右:i 不动 j++ (i 初始化为每圈的startX) res[i][j] = count++;
  • 上->下:j 不动 i++ (j 初始化为每圈的startY) res[i][j] = count++;
  • 右->左:j 不动 i–(j 为上次循环跳出时的值) res[i][j] = count++;
  • 下->上:i 不动 j–(i 为上次循环跳出时的值) res[i][j] = count++;
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0)); //下标从0开始
        int loopCount = n / 2; //奇数如3,循环1圈中间特殊处理 偶数如4,循环2圈
        int startX = 0, startY = 0; //每圈的起始位置
        int count = 1; //各个位置的值 
        int offset = 1; //没圈循环结束, offset - 2
        int i, j;
        while(loopCount--){
            i = startX;
            j = startY;
            //区间保持左闭右开:使用 < 或 >
            for(j = startY; j < startY + n - offset; j++)  res[i][j] = count++;
            for(i = startX; i < startX + n - offset; i++)  res[i][j] = count++;
            for(; j > startY; j-- ) res[i][j] = count++;
            for(; i > startX; i-- ) res[i][j] = count++;
			//一圈结束后 各方向起始位置 ++
            startX++;
            startY++;
			//offset 变大,每边的长度变小
            offset += 2;
        }
        
        //特判奇数值时中间位置的赋值
        int mid = n / 2; //矩阵的位置,奇数如3,中间位置为(1,1) 偶数如4,中间位置为(2,2)
        if(n%2) res[mid][mid] = count;
        return res;
    }
};

你可能感兴趣的:(算法面试题,面试,c++,数据结构)