首页 > 其他分享 >(2/60)有序数组平方、长度最小子数组、螺旋矩阵

(2/60)有序数组平方、长度最小子数组、螺旋矩阵

时间:2024-01-25 22:34:32浏览次数:25  
标签:nums int 复杂度 矩阵 60 ++ 数组 指针

有序数组的平方

leetcode:977.有序数组的平方

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

暴力法

思路

  1. 遍历数组,元素原地替换为自身平方值。
  2. 将数组进行排序。

复杂度分析

时间复杂度:O(N+logN)

空间复杂度:O(1)

注意点

  1. sort(parm1,parm2,options),接收首地址/迭代器、末地址/迭代器、比较函数。
  2. begin()、end()方法返回首、末迭代器。c++里很多容器都有这两个方法。

代码实现

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;
    }
};

相向双指针法

思路

基于1. 原数组有序;2. 元素有正有负两条特性,元素平方后的值,最大值一定出现在两端,利用相向双指针从两端向中间靠拢,寻找每一轮的最大值,倒序赋值给新数组,从而达到排序效果。

  1. 初始化左、右指针、新数组、新数组指针(末位) .

  2. 左右指针对比,找到本轮自身平方最大的元素,填入新数组中。

    若左元素大,则填入左元素,left++,cur--;

    否则,填入右元素,right--,cur--;

  3. 重复2直至left>right,循环结束。

复杂度分析

时间复杂度:O(N)

空间复杂度:O(N),额外开辟了一个等大数组.

注意点

  1. 必须在新开辟数组填入元素,否则修改原数组会污染数据.

代码实现

class Solution {
public:
    // 相向双指针,利用最大值出现在数组两端的特性(有正有负)
    // 两指针向中间靠拢,每次都找到剩余元素中最大的,
    // 将找到的元素倒序插入新数组中,即可完成排序
    vector<int> sortedSquares(vector<int>& nums) {
        int left = 0;
        int right = nums.size() - 1;
        int cur = nums.size() - 1;
        vector<int> arr(nums.size());
        // 右闭原则
        while(left <= right){
            // 每轮取最大的元素,倒序填入
            if(nums[left]*nums[left] > nums[right]*nums[right]){    // left大
                arr[cur--] = nums[left]*nums[left];
                left++;
            }else{  // right大或相等
                arr[cur--] = nums[right]*nums[right];
                right--;
            }
        }

        return arr;
    }
};

长度最小的子数组

leetcode:209. 长度最小的子数组

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

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

暴力法

思路

外层代表终止指针,遍历数组;内层代表起始指针,从0遍历到终止指针。内层遍历过程中起始指针不断后移,同时不断检测是否还满足条件。

  1. 外层循环,移动终止指针i,遍历数组
  2. 内层循环,移动起始指针j,遍历0~i(含i),如果局部和curSum >= target那么就尝试更新(与历史最短比较,如果更短就更新数值)最短值。
  3. 重复2直至遍历完成,返回时检测result是否更新过,若未更新则不存在满足条件的子序列,返回0。

复杂度分析

时间复杂度:O(N)

空间复杂度:O(1)

注意点

  1. 内层循环要使用局部累和curSum,否则用原累和sum会污染数据。
  2. 内层j可以取到i,此时长度为1。

代码实现

class Solution {
public:
    // 暴力法
    // 外层终止指针遍历数组
    // 内层起始指针遍历到终止指针,找到最小值
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0;
        for(int i = 0;i < nums.size();i++){
            sum += nums[i]; 
            if(sum >= target){
                int curSum = sum;
                for(int j = 0;j <= i; ){
                    if(curSum >= target){  
                        // 尝试更新
                        int subLength = i-j+1;
                        result = subLength < result ? subLength : result;

                        curSum -= nums[j++];
                    }else{
                        break;
                    }
                }

            }
        }

        return result == INT32_MAX ? 0 : result;
    }
};

滑动窗口法(同向双指针)

思路

设置同向双指针,利用nums元素是正数的特点,终止指针后移一定使累和增大,起始指针后移一定使累和减小,不存在起始指针回头还是最优解的情况。

  1. 外层循环移动终止指针i,遍历数组,同时计算累和sum
  2. sum >= target时,内层循环移动起始指针j,尝试更新最短长度。
  3. 重复1、2,直至循环完毕。返回时检测result是否更新过,若未更新则不存在满足条件的子序列,返回0。

复杂度分析

时间复杂度:O(N)。虽然两层循环,但i、j整体只会移动N次

空间复杂度:O(1)。无额外空间。

注意点

  1. 内层j可以取到i,此时长度为1。

代码实现

class Solution {
public:
    // 滑动窗口(同向双指针)
    // 因为nums元素都是正数,终止指针后移累和一定增大
    // 起始指针后移累和一定减小,不存在起始指针回头还满足条件的情况
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0;
        // 外层移动终止指针
        for(int i = 0,j = 0;i < nums.size();i++){
            sum += nums[i];
            while(sum >= target && j <= i){
                int subLength = i-j+1;
                result = subLength < result ? subLength : result;

                sum -= nums[j++];
            }
        }

        return result == INT32_MAX ? 0 : result;
    }
};

螺旋矩阵

思路

表现是螺旋形,但是处理时是一环一环地处理。

  1. 声明一个大小为n×n的二维矩阵matrix,并将每个元素初始化为n×n(避免了处理N为奇数的情况)。
  2. 进入循环,循环条件为需要进行的螺旋层数loop大于等于0。
  3. 在每一层中,按照螺旋顺序遍历矩阵的边界,将计数器count的值逐个赋给矩阵对应位置的元素,并将count加1。
  4. 每完成一次螺旋遍历,需要进行的螺旋层数loop减1,同时记录当前层的偏移量offset加1。
  5. 循环结束后,返回生成的螺旋矩阵matrix。

复杂度分析

时间复杂度:O(N^2)。

空间复杂度:O(N^2)。额外声明了二维数组。

注意点

  1. 左闭右开原则,每次只处理到末元素前一个。
  2. 元素初始化为N*N,避免了N是奇数时的处理。

代码实现

class Solution {
public:
    // 左闭右开原则
    vector<vector<int>> generateMatrix(int n) {
        int count = 1;
        int loop = n/2;
        int offset = 0;
        int i=0,j=0;
        // 声明n*n矩阵,元素初始化为n*n
        vector<vector<int>> matrix(n,vector<int>(n,n*n));
        
        while(loop--){
            for(j = offset;j < n - 1 - offset;j++){
                matrix[offset][j] = count++;
            }

            for(i = offset;i < n - 1 - offset;i++){
                matrix[i][j] = count++;
            }

            for(;j > offset;j--){
                matrix[i][j] = count++;
            }
            
            for(;i > offset;i--){
                matrix[i][j] = count++;
            }
            offset++;
        }

        return matrix;
    }
};

标签:nums,int,复杂度,矩阵,60,++,数组,指针
From: https://www.cnblogs.com/tazdingo/p/17988334

相关文章

  • loj 6095 花神的嘲讽计划 题解
    题目哈希记录每个\(k\)长度的串,询问的时候可以拿主席树或二分,这里说下二分。将\(n-k+1\)个串从小到大排序,以哈希值为第一关键字,序号为第二关键字。每次询问直接查找大于等于当前哈希值的位置即可,找到之后判断一下合不合法即可。具体看代码:#include<bits/stdc++.h>typede......
  • leecode数组
    217.存在重复元素给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。示例1:输入:nums=[1,2,3,1]输出:true示例2:输入:nums=[1,2,3,4]输出:false示例 3:输入:nums=[1,1,1,3,3,4,3,2,4,2]输出:true......
  • js中数组反转的方法总结
    1.常用的方法reverse()[1,2,3,4].reverse()  //[4,3,2,1]2.采用for循环方式使用递减循环遍历的方式,将元素一次存入新的数组中,新数组就是反转后的新数组constdataRef=[1,2,3,4]constnewArr:any[]=[]for(leti=dataRef.length-1;i>=0;i--){ne......
  • 代码随想录算法训练营第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
    977.有序数组的平方给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/错误的vector遍历方式,这会导致访问越界!!!while(nums[flag]<0)flag++;倒也不难,我......
  • 紫光展锐T760_安卓核心板性能参数|5G国产核心板方案
    展锐T760核心板是一款国产5G芯片的智能模块,采用了紫光展锐T760制程工艺,采用台积电6nm工艺制造,具有出色的能效表现。它采用了主流的4+4架构的八核设计,其中包括4颗2.2GHzA76核心和4颗A55核心,板载内存单元最高可达8GBRAM+256GBROM,运行Android13以上操作系统,性能强大且功能丰......
  • 矩阵号:日入100+,八大提示词(Prompt)使用技巧
    最近在搞头条矩阵,发现自己的指令写的太烂了,一个指令将会决定你的写作质量。收益比较拉垮,50个号收益好的,也就这么几个号。于是我扒了一些提示词的操作技巧,分享一下自己的学习心得。先说理论知识,实操放文章最后。我们与GPT沟通交流时,可以用到乔哈里()沟通视窗模型,它分为......
  • 收集Stream流的数据到集合或数组中
    1publicstaticvoidmain(String[]args){2List<String>list=newArrayList<>();3list.add("张三");4list.add("李四");5list.add("王武");6list.add("王武"......
  • P3374 【模板】树状数组 1(线段树)
    【模板】树状数组1题目描述如题,已知一个数列,你需要进行下面两种操作:将某一个数加上x求出某区间每一个数的和输入格式第一行包含两个正整数n,m,分别表示该数列数字的个数和操作的总个数。第二行包含n个用空格分隔的整数,其中第i个数字表示数列第i项的初始值......
  • P1962 斐波那契数列(矩阵快速幂)
    #include<bits/stdc++.h> #defineintlonglong usingnamespacestd; intn,a[3],m=1e9+7,c[3][3],b[3][3],x[3][3],a1[3]; voidfirst() { for(inti=1;i<=2;i++) for(intj=1;j<=2;j++)x[i][j]=0; for(inti=1;i<=2;i++) ......
  • P8659 [蓝桥杯 2017 国 A] 数组操作 题解
    题目链接:洛谷或者蓝桥杯或者C语言中文网几个OJ的AC记录:忘了哪个OJ的:洛谷:C语言中文网:蓝桥杯:emmmmmmm,好像每个OJ给的时限和空间还不一样,蓝桥杯官方还给了$3s$和$2G$,C语言中文网机子比较老可能,挺卡常的,开了个究极快读和指令集就过去了,也可以自己调下重构常数,偷懒......