代码随想录刷题day02

977.有序数组的平方

977有序数组的平方 - 力扣(LeetCode)

方法1:双指针比较左右最大数

思路:

1.定义左指针l=0,右指针r=nums.size()

2.开始比较左右指针的平方大小,若是右边的指针是更大的一方,则从后开始,放入新创建的数组arr中,然后r--;若左边的指针是更大的一方,则继续放入arr,并循环直到l<r,即原数组的所有元素都被取到。最后返回arr

3.由于只在循环插入arr的时候进行数组元素平方大小的遍历,因此时间复杂度是O(n)

代码:

class Solution {

public:

    vector<int> sortedSquares(vector<int>& nums) {

            int l = 0,r = nums.size();

            vector<int> arr(nums.size());

            while(l < r){

                for(int i = nums.size()-1;i >= 0 ;i--){

                    if(nums[l] * nums[l] <= nums[r-1] * nums[r-1]){

                        arr[i] = nums[r-1] * nums[r-1];

                        r--;

                    }

                    else{

                        arr[i] = nums[l] * nums[l];

                        l++;

                    }

                }

            }

            return arr;

    }

};

方法2 暴力做法

思路:直接所有数平方,然后sort函数排序,时间复杂度O(n+nlogn)

代码:

class Solution { public: vector<int> sortedSquares(vector<int>& nums) {

for(int i = 0;i < nums.size();i++) {

nums[i] = nums[i] * nums[i]; }

sort(nums.begin(),nums.end()); return nums; }

};

209 长度最小的子数组

209 长度最小的子数组 - 力扣(LeetCode)

思路:由于限制1是要求找出最小区间;限制2是区间内的和大于等于target,因此考虑用滑动窗口动态寻找目标区间的长度大小

1.定义l=0为窗口的左端点,定义累计和sum用来和target比较,从数组的第一个元素i=0开始累加,直到sum >= target,此时窗口的长度为i-l+1,需要判断是否为最小长度,因此定义length用来存储每次sum判断的区间长度

2.只有遍历完整个区间才能找到满足条件的最小区间,因此窗口的左端点l++,然后sum-nums[l]。此时窗口内部的sum一定不满足条件,因此sum[i++],继续添加数组元素到区间内。此时窗口为动态向右滑动的过程,当i到达右边界,而区间内的sum仍然大于target,就需要继续移动窗口左端点,此时区间长度逐渐减小,最后跳出sum>=target的条件后获得的length即为最小区间长度

3.最后判断是否length和初始定义的区间长度一致,如果一致,说明整个的区间和都不满足大于等于target,因此返回0


代码:

class Solution { public: int minSubArrayLen(int target, vector<int>& nums) {

int n = nums.size();

int l = 0,sum = 0; int length = n + 1;

for(int i = 0;i < n;i++) {

sum += nums[i];

while(sum >= target) {

length = min(length,i - l + 1);//l是窗口的左端点,i是窗口的右端点

sum -= nums[l++];//窗口向右滑动一格 } }

return length != n + 1 ? length : 0;

} };

59. 螺旋矩阵 II - 力扣(LeetCode)

 思路:

碰到类似需要进行多个判断的矩阵,可以考虑使用偏移量来减少判断次数,试用题目像:马走日,国际象棋的骑士每次只能走八个格子等。

本题的数字填充有四个方向,因此假设中间值为(x,y),则可以获得其余四个方向紧挨的数字的偏移量,将上下左右四个方向用数字0,1,2,3表示,并对4取模,使得每次到达边界的时候可以有效的更换方向,然后将x的偏移量表示为{-1,0,1,0},y的偏移量表示为{0,1,0,-1},最后横纵坐标等于之前的加上偏移量。

代码:

class Solution {

public:

    vector<vector<int>> generateMatrix(int n) {

    vector<vector<int>> matrix(n, vector<int>(n, 0));

            int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};//设置x和y轴的偏移量

            int x = 0,y = 0,d = 1;//d=1此时先往右填充

            for(int i = 1;i <= n * n;i++){

                matrix[x][y] = i;

                int a = x + dx[d],b = y + dy[d];//此时的横纵坐标由原来的坐标加对应轴的偏移量获得

                if(a < 0 || a >= n || b < 0 || b >= n || matrix[a][b] != 0){//如果横纵坐标都越界,或即将填充的格子有元素

                    d = (d + 1) % 4;//更换方向

                    a = x + dx[d],b = y + dy[d];

                }

                x = a,y = b;

            }

            return matrix;  

    }

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值