Leetcode 977-有序数组的平方 | LeetCode209-长度最小的子数组 | Leetcode59-螺旋矩阵

Leetcode 977-有序数组的平方 | LeetCode209-长度最小的子数组 | Leetcode59-螺旋矩阵

Leetcode 977-有序数组的平方

  • 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]

示例 2: 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]

方法一-双指针法


class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
    int left = 0;
    int n = nums.size();
    int right = n-1;
    vector <int>result(n,0);              //  定义一个长度为nums.size()的动态数组
    while(left<=right)                               
    {
    if(nums[left] * nums[left]<nums[right] * nums[right])
    {
    result[n-1]=nums[right] * nums[right];     //比较前后俩个指针指向的值将大的数从后往前排
    n--;
    right--;
    }
    else
    {
     result[n-1]=nums[left] * nums[left];
     n--;
     left++;
    }
    }
    return result;
    }
};

思考:

  • 这个数组为有序数组,那么即使前面有负的,数组平方的最大值只能是在数组的倆端,不是在左边就是右边,不可能是在中间
    由此想到双指针做法,left从前往后,right从后往前,将大的放在新创建数组的末端
    注意循环终止的条件,这边left==right也是有意义的

方法二-暴力排序


class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {
        for (int i = 0; i < A.size(); i++) {
            A[i] *= A[i];
        }
        sort(A.begin(), A.end()); // 快速排序
        return A;
    }
};

LeetCode209-长度最小的整数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0 。


输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

方法一-暴力解法


class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
    int result = INT_MAX;         //INT32_MAX可以看成一个相当大的数
    int sum = 0;
    int sublength = 0;
    int n = nums.size();
    if(n==0) return 0;
    for(int i = 0;i<n;i++)      //i为最小子数组的起点
    {
    sum = 0;                //每次重新移动起点都要将sum赋值为0
        for(int j = i;j<n;j++)  //j为最小子数组的终点
        {
        sum += nums[j];
        if(sum>=target)             //当发现子序列超过sum的时候更新result
        {
        sublength = j-i+1;
        result = result <sublength ? result : sublength;
        break;              //找到最小子序列时跳出循环
        }
        }
    }
    return result == INT_MAX ? 0 : result;        //result没有被赋值的话就返回0
    }
};
  • 思路:用俩个for循环寻找子列
  • INT_MAX = 2^31-1,INT_MIN= -2^31. 可以看出是一个相当大的数和一个相当小的数,如果想要得到数组中最小值,可以先将最小值赋值为INT_MAX ;
    同理如果想要得到数组中最大值,可以先将最大值赋值为INT_MIN ;

方法二-滑动窗口


class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
    int result = INT_MAX;
    int sum = 0  ;//滑动窗口之和
    int sublength = 0; //滑动窗口的长度
    int i = 0; //滑动窗口的起始位置
    int n = nums.size();
    for(int j = 0; j<n;j++)
    {
    sum += nums[j];
    while(sum>=target)
    {
    sublength = j-i+1;
    result = result< sublength ? result :sublength;
    sum -= nums[i++];   //滑动指针 从sum中减去起始位置的值并且 移动起始位置
    }
    }
    return result==INT_MAX ? 0 : result;  //判断是否能找到最小的子数组不能则返回0
    }
};

思路:
利用滑动窗口(起始就是双指针)
for循环中遍历的是 窗口末端位置。为什么只用一个for循环便利就能达到预期效果呢?这边类似一个滑动的窗口,当窗口的末端位置向后移动时,满足sum>=target的条件后就要将起始位置的指针移动,满足条件的话不断更新result的值,使其能成为最小的子序列。

Leetcode59-螺旋矩阵

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
    vector<vector<int>> res(n,vector<int>(n,0));    //使用vector定义一个二维数组
    int startx = 0,starty = 0; //定义每循环一个圈的起始位置
    int loop = n/2; //每个圈循环的次数
    int middle = n/2; //矩阵中间的位置
    int count = 1;  //给矩阵中每一个空格赋值
    int offset = 1; //勇于控制每一条边遍历的长度
    int i,j;
    while(loop--)
    {
    i = startx;
    j = starty;
    
        
        //四个for转一圈
    for(j = starty;j<n-offset;j++)  //上行从左到右(左闭右开)
    {
        res[startx][j]=count++;
    }
    for(i=startx;i<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++;           //从第二圈开始起始位置都各自+1
    offset+=1;          //offset控制每一条边遍历的长度
    }
    if(n%2)
    {
        res[middle][middle]=count;  //如果n为奇数的话,需要单独给矩阵最中间的值赋值
    }
        return res;
    }
};

  • 思路: 坚持循环不变量-每次循环里都要遵循同一套规则,必须保持一些变量的不可变。 这边始终坚持左闭右开的原则
    —填充上行从左到右;填充右列从上到下;填充下行从右到左;填充左列从下到上
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值