代码随想录算法训练营第二天 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

代码随想录算法训练营第二天 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

题目(力扣)

题解

977. 有序数组的平方

  • 解法:双指针
  • 代码
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
		vector<int> square;
		int left=0, right=nums.size()-1;
		while (right!=left) {
			if (abs(nums[left]) <= abs(nums[right])) {
				square.push_back(pow(nums[right], 2));
				right--;
				continue;
			}
			square.push_back(pow(nums[left], 2));
			left++;
		}
        square.push_back(pow(nums[left], 2));
		reverse(square.begin(),square.end());
		return square;
    }
};

209. 长度最小的子数组

  • 心路历程:第一遍做没读懂题,题目需要的是子数组,我以为是其中的元素组成的新数组就可以,结果错。后来想到暴力法的思路,不过没实践,直接看的时间复杂度O(n)的解法。
  • 高效解法:滑动窗口法:其实从动画中可以发现滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。(来源:代码随想录
  • 问题:
  1. 时间复杂度O(n)?
    我当时也有这个疑问,不过我想的是这个跟两层for循环显然不一样。计算过程:一层for循环遍历n个元素,循环里面算入总和被访问算一次、窗口划出减掉算一次,共两次,O(2*n)=O(n).
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int sum = 0;
        int i = 0;
        int sublength = 0;
        int result = INT32_MAX;
        for (int j=0; j<nums.size(); j++) {
        	sum += nums[j];
        	while(sum>=s) {
        		sublength = j - i + 1;
        		result = sublength < result ? sublength : result;
        		sum -= nums[i];
        		i++;
			}
		}
		return result==INT32_MAX ? 0 : result;
    }
};

59. 螺旋矩阵II

  • 心路历程:第一遍看题没思路,以前也没看见过,遂看解析。试着理解代码,有了大体了解后(代码也记的差不多)开始敲代码。
    • 问题:
    1. 数组越界:因为一圈螺旋后i和j不在第二圈起始位置,因此需要将ij重定位到新的startx和starty上;
    2. 二维vector数组定义错误:刚开始看carl代码没注意到这个细节,自己动手时以为返回vector<vector<int>>就直接定义就行。结果报错:
Line 1034: Char 9: runtime error: reference binding to null pointer of type 'std::vector<int, std::allocator<int>>' (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:9

对比发现定义不一样,初始化方法如下:

代码说明
vector v1;保存类型为 T 对象。默认构造函数 v1 为空。
vector v2(v1);v2 是 v1 的一个副本。
vector v3(n, i);v3 包含 n 个值为 i 的元素。
vector v4(n);v4 含有值初始化的元素的 n 个副本。

且,vector构造函数vector(int nSize,const t& t)​:创建一个vector,元素个数为nSize,且值均为t

我的代码:vector<vector<int>> matrix
carl代码:vector<vector<int>> matrix(n, vector<int>(n,0))

可以看到,定义时不填写参数时,调用的默认构造函数使vector为空,此时它并不能当二维数组使用,因此操作会越界;利用C/C++数组存储特点构造数组的数组,并将一维数组元素初始化为存储一维数组的vector即为2维数组。

  • 代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
		vector<vector<int>> matrix(n,vector(n,0));
		int loop = n / 2;
		int startx = 0, starty = 0;
		int offset = 1;
		int count = 1;
		while(loop--) {
			int i = startx;
			int j = starty;
			for (; j<n-offset; j++) {
				matrix[i][j] = count++;
			}            // 这里和卡哥的不一样,直接初始时定位i,j
			for (; i<n-offset; i++) {
				matrix[i][j] = count++;
			}
			for (; j>starty; j--) {
				matrix[i][j] = count++;
			}
			for (; i>startx; i--) {
				matrix[i][j] = count++;
			}
            startx++;
            starty++;
            offset++;
		}
		if (n % 2) {
			int mid = n / 2;
			matrix[mid][mid] = count;
		}
		return matrix;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值