代码随想录算法训练营第二天| 977. 有序数组的平方、209. 长度最小子数组、59.螺旋矩阵II、数组总结
目录:
977.有序数组的平方
209.长度最小的子数组
1.暴力输出法
2.滑动窗口法
59.螺旋矩阵II
总结:
今日收获:
977.有序数组的平方
因为是递增且有负数的数组,那么他们的平方如果还是按照原来的顺序排列的话,是两边的值会相对大,所以用两个指针分别从左右两侧寻找新数组里面的元素
我的错误代码:
class Solution {
public:vector<int> sortedSquares(vector<int>& nums) {int size = nums.size();vector<int> result;int newIndex = size - 1;int left = 0;int right = size - 1;while(left < right){if(nums[left]*nums[left] > nums[right]*nums[right]){result[newIndex] = nums[left]*nums[left];left++;}else{result[newIndex] = nums[right]*nums[right];right--;}newIndex--;}return result;}
};
代码出现的问题:
1.runtime error: applying non-zero offset 16 to null pointer (stl_vector.h)
一开始定义vector有问题: vector <int> result(nums.size(),0); 括号里面先是大小,然后是数组的数值
2.while(left < right){ 如果没有相等,那就少了left=right指向同一个数组元素的情况了
正确代码如下:
class Solution {
public:vector<int> sortedSquares(vector<int>& nums) {int size = nums.size();vector<int> result(size,0);int newIndex = size - 1;int left = 0;int right = size - 1;//如果没有相等,那就少了left=right指向同一个数组元素的情况了while(left <= right){if(nums[left]*nums[left] > nums[right]*nums[right]){result[newIndex] = nums[left]*nums[left];left++;}else{result[newIndex] = nums[right]*nums[right];right--;}newIndex--;}return result;}
};
209.长度最小的子数组
1.暴力输出法
用两个for循环输出所有的子集,当找到第一个sum>=target的时候就马上停止,然后需要创建一个sum还有一个子集的长度大小,这样每一个不一样的起始位置之间都可以进行对比,留下来长度最小的那个
接下来又是我的错误代码展示:(好像就没写对过sad)
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int result = INT_MAX;int length = 0;int sum = 0;int size = nums.size();for(int i = 0; i < size; i++){for(int j = i; j < size; j++){sum += nums[j];if(sum >= target){length = j - i + 1;result = result < length ? result : length; //把result的初始值设成一个相对较大的数,这样第一次赋值一定是lengthbreak;}}}return result == INT_MAX ? 0 : result;}
};
错误分析:没有在每一次更换新的起始位置的时候把sum的值重新赋为0,这样的话即使开始新的起始位置,留存的子集还是上一个起始位置时得到的结果,没有办法做到更新
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int result = INT_MAX;int length = 0;int sum = 0;int size = nums.size();for(int i = 0; i < size; i++){sum = 0;for(int j = i; j < size; j++){sum += nums[j];if(sum >= target){length = j - i + 1;result = result < length ? result : length; //把result的初始值设成一个相对较大的数,这样第一次赋值一定是lengthbreak;}}}return result == INT_MAX ? 0 : result;}
};
2.滑动窗口法
for循环里面的j表达的是终止位置,起始位置默认从0开始,当终止位置一位一位向前移的时候,直到他们的和 > target,起始默认位置就加1,这样就比暴力解法省去了一个一个代入算的繁琐过程
我的代码终于写对了:
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int size = nums.size();int result = INT_MAX;int length = 0;int sum = 0;int leftIndex = 0;for(int i = 0; i < size; i++){sum += nums[i];while(sum >= target){length = i - leftIndex + 1;sum -= nums[leftIndex++];result = result < length ? result : length;}}return result == INT_MAX ? 0 : result;}
};
我觉得这个和暴力解法是有相似处,代码逻辑搞明白之后基本上能立马写出来,就是少了一个for循环的概念
59.螺旋矩阵II
1.需要把1到n平方按照顺时针的方式排列组合,也就是排列成矩阵(二维数组)的模式,经过推演,发现当n为偶数的时候,一共需要转n/2圈,但是当n为奇数的时候( n%2 = 1),还是需要n/2圈(结果为int这个数据类型,会保留整数部分),但是需要把最后一个值放到中间
---->创建二维数组:vector<<int>vector> matrix = (n, vector<int>(n,0))
2.每一行的赋值都要有同一性,在这里我们左闭右开(参考二分法用到的概念),所以平常我们想要取到整行的元素的话,应该是从0开始,i<nums.size(),这样可以取到所有的元素,从0到size-1,但是这一次是左闭右开,也就是右边少取一个,是 i<size-1,要转第二圈的话就是i< size-2。所以这里还要再引入一个offset的概念,每转完一圈,这个offset++
3.需要写四个for循环,左到右,上到下,右到左,下到上
我的错误代码和debug记录:
class Solution {
public:vector<vector<int>> generateMatrix(int n) {//创建一个二维数组vector<vector<int>> matrix = vector(n, vector<int>(n,0));//创建每一次赋给数组元素的值int val = 1;//数组的行列起始indexint startI = 0;int startJ = 0;//根据不同的圈,需要减去的会变化的值int offset = 1;int loop = n/2;while(loop != 0){//赋值给第0行的每一列,所以for循环里面是jfor(int j = startJ; j < n - offset; j++ ){int[i][j] = val++;}//赋值给第j列的每一行,所以for循环里面是ifor(int i = startI; i < n - offset; i++ ){int[i][j] = val++;}//赋值给第i行的每一列,所以for循环里面是j,这回往回走,要变成减法了for( j = j; j > startJ; j-- ){int[i][j] = val++;}//赋值给第j列的每一行,所以for循环里面是ifor(i = i; i > startI; i-- ){int[i][j] = val++;}startI++;startJ++;offset++;loop--;}if(n%2 == 1){int[n/2][n/2] = n*n;}return matrix;}
};
- 1.error: decomposition declaration cannot be declared with type 'int'; declared type must be 'auto' or reference to 'auto' int[i][j] = val++; -> 再定义完二维数组之后,应该直接用matrix[i][j],不知道我怎么用了int?
- use of undeclared identifier 'i' matrix[i][j] = val++; -> 第一个for循环里面用的是没有定义的i,可以用startI,反正都是对的
- error: use of undeclared identifier 'j' matrix[i][j] = val++; -> 同样的错误,如果再用上一把的极值也就是n-offset实在是太麻烦了,所以可以在一开始的时候直接定义好int i,j,这样就可以直接使用了
- runtime error: addition of unsigned offset to 0x607000000020 overflowed to 0x606b9b8170b8 (stl_vector.h) -> 出现这个问题说明在给二维数组赋值时的index是有问题的,所以在纸上过了一遍赋值的过程,在最后i和j都会变成0,所以可以是i++,j++,或者 i = startI 和 j =startJ,然后两个start++
在纸上推导的过程:
debug之后的代码:
class Solution {
public:vector<vector<int>> generateMatrix(int n) {//创建一个二维数组vector<vector<int>> matrix = vector(n, vector<int>(n,0));//创建每一次赋给数组元素的值int val = 1;//数组的行列起始indexint startI = 0;int startJ = 0;//根据不同的圈,需要减去的会变化的值int offset = 1;int loop = n/2;int i,j;while(loop != 0){i = startI;j = startJ;//赋值给第0行的每一列,所以for循环里面是jfor(j = startJ; j < n - offset; j++ ){matrix[i][j] = val++;}//赋值给第j列的每一行,所以for循环里面是ifor(i = startI; i < n - offset; i++ ){matrix[i][j] = val++;}//赋值给第i行的每一列,所以for循环里面是j,这回往回走,要变成减法了for( j = j; j > startJ; j-- ){matrix[i][j] = val++;}//赋值给第j列的每一行,所以for循环里面是ifor(i = i; i > startI; i-- ){matrix[i][j] = val++;}startI++;startJ++;offset++;loop--;}if(n%2 == 1){matrix[n/2][n/2] = n*n;}return matrix;}
};
可以精进的地方:
1.while后面的括号里面如果只放一个变量,那么就是这个变量为真的时候可以运行,也就是 loop != 0,所以可以直接换成loop
2.while大括号里面的最后需要 loop--,可以直接把这个放在while判断语句的括号里面
3.for循环里面,如果第一个语句不需要给变量赋值,比如在第三四个for循环里面都是 j = j,那么直接不用写这句话也是可以的
最后精进的版本:
class Solution {
public:vector<vector<int>> generateMatrix(int n) {//创建一个二维数组vector<vector<int>> matrix = vector(n, vector<int>(n,0));//创建每一次赋给数组元素的值int val = 1;//数组的行列起始indexint startI = 0;int startJ = 0;//根据不同的圈,需要减去的会变化的值int offset = 1;int loop = n/2;int i,j;while(loop--){i = startI;j = startJ;//赋值给第0行的每一列,所以for循环里面是jfor(j = startJ; j < n - offset; j++ ){matrix[i][j] = val++;}//赋值给第j列的每一行,所以for循环里面是ifor(i = startI; i < n - offset; i++ ){matrix[i][j] = val++;}//赋值给第i行的每一列,所以for循环里面是j,这回往回走,要变成减法了for( ; j > startJ; j-- ){matrix[i][j] = val++;}//赋值给第j列的每一行,所以for循环里面是ifor(; i > startI; i-- ){matrix[i][j] = val++;}startI++;startJ++;offset++;}if(n%2 == 1){matrix[n/2][n/2] = n*n;}return matrix;}
};
总结:
今日收获:
开始感到学习知识的快乐了,睡觉之前也想要再打开电脑看看,当然学习时间还是挺长的,可能还是6h左右,但是学到了很多东西就不亏,而且这次已经可以在看完carl的视频之后自行写代码了,并且自己debug
代码随想录算法训练营第二天| 977. 有序数组的平方、209. 长度最小子数组、59.螺旋矩阵II、数组总结相关推荐
- 代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II。
代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II. 977.有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II 977.有序数组的 ...
- 代码随想录算法训练营第二天| 977有序数组平方、207最小子数组、59螺旋矩阵II。
977.有序数组的平方 力扣题目链接 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 示例 1: 输入:nums = [-4,-1, ...
- 代码随想录算法训练营第二天| 977. 有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II 。
977. 有序数组的平方 题目链接 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 暴力解法: class Solution {pu ...
- Leonard代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II。
第一章数组 (今日任务) 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结 建议大家先独立做题,然后看视频讲解,然后看文章讲解,然后在重新做一遍题,把题目AC,最后整理 ...
- 代码随想录算法训练营第二天 | LeetCode977.有序数组的平方 ,209.长度最小的子数组,59.螺旋矩阵II
代码随想录算法训练营第二天 | LeetCode977.有序数组的平方 ,209.长度最小的子数组,59.螺旋矩阵II 一. LeetCode977.有序数组的平方 1. 题目链接[LeetCode9 ...
- 代码随想录算法训练营第二天 | LeetCode977有序数组的平方 、209长度最小的子数组、 59.螺旋矩阵II
--------------------------- 977.有序数组的平方 #include <iostream> #include <algorithm> #includ ...
- 代码随想录算法训练营第二天|LeetCode977.有序数组的平方,209.长度最小的子数组, 59.螺旋矩阵II
题目连接:977.有序数组的平方 暴力法:将数组所有元素平方然后再排序(未利用题目条件:原始数组按照非降序排列) 双指针法:数组中各元素符号有三种情况:①所有元素非负(将数组中元素平方即可).②所有元 ...
- 代码随想录算法训练营第二天|LeetCode977.有序数组的平方、LeetCode209.长度最小的子数组、LeetCode59.螺旋矩阵II。
LeetCode977.有序数组的平方 题目链接:LeetCode977.有序数组的平方 暴力解法: class Solution { public:vector<int> sortedS ...
- 代码随想录算法训练营第二天|LeetCode977.有序数组的平方、LeetCode209.长度最小的子数组、LeetCode59.螺旋矩阵Ⅱ
算法训练营打卡第二天,今天的前两道题目重点练习了双指针的用法,最后一道题目将边界条件的限定作为关键点,额外锻炼了逻辑能力. LeetCode977.有序数组的平方 题目链接 https://leetc ...
最新文章
- jQuery源码分析-each函数
- 线性表adt的c语言表达,抽象数据类型定义(ADT)
- 作业21-加载静态文件,父模板的继承和扩展
- 2017西安交大ACM小学期数论 [阅兵式]
- mvc html.antiforgerytoken,MVC Html.AntiForgeryToken() 防止CSRF***
- java中单例模式用法详解
- html 最小长度单位,html见长度单位尺寸单�?CSS布局HTML
- 「Algospot」龙曲线DRAGON
- 客户服务器与p2p文件分发,P2P大文件分发技术 | 点量软件
- 新手必看的入门编程教程
- 【自然语言处理】【文本风格迁移】基于风格实例的文本风格迁移
- WPS中的word如何取消英文首字母大写
- ROS多设备组网(WSL+miniPC+Nv Orin)
- HCIE - 2204-MPLS
- JAVA第二次作业《胖瘦程度计算》
- DR/BDR是解决什么问题的?
- Unity加载优化-将基于LZMA的ab压缩方案修改为LZ4压缩的过程
- Docker 4 之 Docker 客户端和守护进程
- 推荐一个免费、轻巧、简单好用的Excel工具包
- 首发!小牛电动股权巨震:李一男、胡依林大幅减持,纪源资本退出