数组第二天,先刷题。
977 有序数组的平方
这道题如果是平时我就直接sort了,想练一下指针,我倒是想到了一头一尾直接比较,但是又不知道如何在本数组内修改,为难了一会儿,看看录哥思路,好嘛果然也是开新数组,那就简单了。学到了vector的新用法,vector如果只是vector<int>arr的话不会给分配空间,直接引用下标赋值会出错,需要给一个初始空间。代码如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i=0,j=nums.size()-1,k=nums.size()-1;
vector<int>new1(nums.size());
while(i<=j)
{
if(nums[i]*nums[i]<nums[j]*nums[j])
{
new1[k--]=nums[j]*nums[j];
j--;
}
else
{
new1[k--]=nums[i]*nums[i];
i++;
}
}
return new1;
}
};
- 长度最小的子数组
这道题考察滑动窗口,题目不难,不过题目描述里的一句话给我看乐了
暴力法很简单,两道循环就行,时间复杂度O(n^2),力扣会超时,我就不写了。
滑动窗口法,重点在于去遍历窗口的结束位置,在for循环内约束窗口,一旦超过target和值就修改窗口起始位置,并且更新长度与sum。代码还是很好理解的,如下:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i=0,sum=0,len=INT32_MAX;
for(int j=0;j<nums.size();j++)
{
sum+=nums[j];
while(sum>=target)
{
int len1=j-i+1;
len=min(len,len1);
sum-=nums[i++];
}
}
return len==INT32_MAX?0:len;
}
};
- 螺旋矩阵||
巧了,前不久刚做过这道题,用的方法比较笨四个while循环四个方向,行和列对应加减。其实也是挺容易出错的,需要调试。不过是用静态数组,并且也会空出第0行第0列,洛谷上有题,代码如下
#include <bits/stdc++.h>
using namespace std;
int a[15][15];
int main() {
int n;
scanf("%d", &n);
int k = 1;
int x = 1, y = 0;
int sum = n * n;
while (k <= sum)
{
while (y < n && !a[x][y + 1])
a[x][++y] = k++;
while (x < n && !a[x + 1][y])
a[++x][y] = k++;
while (y > 1 && !a[x][y - 1])
a[x][--y] = k++;
while (x > 1 && !a[x - 1][y])
a[--x][y] = k++;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
printf("%3d",a[i][j]);
printf("\n");
}
return 0;
}
看了录哥的方法,非常清晰,变量定义得特别合适。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>>res(n,vector<int>(n,0));
int sx=0,sy=0,cnt=1;
int loop=n/2,offset=1,mid=n/2;
int x,y;
while(loop--)
{
x=sx;y=sy;
for(y;y<n-offset;y++)res[x][y]=cnt++;
for(x;x<n-offset;x++)res[x][y]=cnt++;
for(;y>sy;y--)res[x][y]=cnt++;
for(;x>sx;x--)res[x][y]=cnt++;
sx++;
sy++;
offset++;
}
if(n%2)res[mid][mid]=cnt;
return res;
}
};
学完以后的感觉是,模拟不难,双指针也不难,但是竞赛用代码跟算法代码真的差别很大。竞赛代码更多是面向结果编程,只要输出符合要求,管你内存是怎么放的,没有那么多要求。总之,算法路上还需多努力!