数组

977.有序数组的平方

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

示例:

算法练习-day2_数组

看到此题,我大致有两种思路1.先将数组中元素平方,然后利用sort排序。2.利用双指针,准备工作:开辟一个大小等于nums的数组arr,两个指针一个指向数组开头,一个指向末尾,定义一个用于插入arr的指针;插入依据:左指针指向数组的平方大于右指针指向数组的平方,插入左元素,插入指针向前移动,右指针做法类似;循环终止:左指针大于右指针。

方法1代码:

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

方法2代码:

    vector<int> sortedSquares(vector<int>& nums) {
        //准备工作
        vector<int> arr(nums.size());
        int len=nums.size()-1;
        int left=0,right=nums.size()-1;
        while(left<=right)//终止条件
        {
            int leftNum=nums[left]*nums[left];//左指针元素的平方
            int rightNum=nums[right]*nums[right];//右指针元素的平方
            if(leftNum>rightNum)//插入条件
            {
                arr[len--]=leftNum;
                left++;
            }
            else
            {
                arr[len--]=rightNum;
                right--;
            }
        }
        return arr;
    }

209.长度最小的子数组

题意:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和≥target的长度最小的 连续子数组,并返回其长度。如果不存在符合条件的子数组,返回0。

示例:

算法练习-day2_数组_02

本题有两种思路1.暴力求解,两次for循环,最外面循环就是起始位置,内层for循环表示从开头到该位置的和,若大于等于target,则记录len,然后跳出。2.双指针,利用双指针模拟滑动窗口,只需要一次for循环,遍历滑动窗口的右边界,让左边界和右边界开始都为0,然后让右边界不断移动,若发现有大于等于target的情况,记录len,然后对左边界不断缩小。

方法1代码:

    int minSubArrayLen(int target, vector<int>& nums) {
        int len=INT_MAX;
        for(int i=0;i<nums.size();i++)
        {
            int Num=0;
            for(int j=i;j<nums.size();j++)
            {
                Num+=nums[j];
                if(Num>=target)
                {
                    len=min(len,j-i+1);
                    break;
                }
            }
        }
        return len==INT_MAX?0:len;
    }

方法2代码:

    int minSubArrayLen(int target, vector<int>& nums) {
        int sum=0;//窗口中元素的和
        int len=INT_MAX;//窗口长度
        int left=0;//窗口起始位置
        for(int right=0;right<nums.size();right++)
        {
            sum+=nums[right];
            while(sum>=target)//满足条件时,保存窗口长度
            {
                len=min(len,right-left+1);
                sum-=nums[left];
                left++;
            }
        }
        return len==INT_MAX?0:len;
    }

从上述思路我们不难看出,方法1的时间复杂度为O(n^2),是通过不了leetcode的;而方法2,我们使用双指针的思想,将两次遍历的事件缩短为了一次,时间复杂度降低了一倍,为0(n)。这里我们还需要理解时间复杂度的概念:这里时间复杂度判断标准是数组中元素的遍历次数,我们只遍历了一次,所有while并不会增加时间复杂度。

59.螺旋矩阵II

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

示例:

算法练习-day2_数组_03

本题并没有涉及算法的思路,主要就是考察逻辑的严谨性,根据题目给出的边界,我们需要控制好上下左右边界,让指针在该范围内进行持续输出,代码如下:

    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> arr(n,vector<int>(n));
        int row=0,col=0,rowMax=n-1,colMax=n-1;
        int sum=1;//输入arr中的元素
        while(sum<=n*n)//循环条件
        {
            for(int i=col;i<=colMax;i++)//上行
            {
                arr[row][i]=sum++;
            }
            row++;
            for(int i=row;i<=rowMax;i++)//右列
            {
                arr[i][colMax]=sum++;
            }
            colMax--;
            if(row<rowMax)//判断是否还有行需要输出
            {
                for(int i=colMax;i>=col;i--)//下行
                {
                    arr[rowMax][i]=sum++;
                }
                rowMax--;
            }
            if(col<colMax)//判断是否还有列需要输出
            {
                for(int i=rowMax;i>=row;i--)//左列
                {
                    arr[i][col]=sum++;
                }
                col++;
            }
        }
        return arr;
    }