LeetCode977. 有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/

思路:看到题目的第一想法是使用暴力法:数组里的每个元素都平方一下,再排个序。

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

思考:可以使用双指针法。题目说了数组是有序的,那么该数组平方的最大值就在数组的两端,要么最左边,要么最右边,不可能在中间。

考虑用双指针法,i指向原数组起始位置,j指向原数组终止位置。

再定义一个新的数组,用于存放最终结果,和原数组一样的大小。

如果A[i]*A[i] ≤ A[j]*A[j],那么result[k] = A[j]*A[j],k- -,j- -;

如果A[i]*A[i] > A[j]*A[j],那么result[k] = A[i]*A[i],k- -,i++;

C++代码如下:

class Solution
{
public:
vector<int> sortedSquares(vector<int>& nums)
{
vector<int> A(nums.size(), 0);  //最后的结果存放在这个新数组中
int i = 0;
int j = nums.size() - 1;
int len = nums.size() - 1;
while(i < j)
{
if((nums[i]*nums[i]) <= (nums[j]*nums[j]))
{
A[len] = nums[j]*nums[j];
len--;
j--;
}
else if((nums[i] * nums[i]) > (nums[j] * nums[j]))
{
A[len] = nums[i]* nums[i];
len--;
i++;
}
}
A[0] = nums[i] * nums[i];
return A;
}
};

LeetCode209. 长度最小的子数组

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/

思路:暴力法,用两层for循环,不断寻找符合条件的子序列,再找出长度最短的子序列。时间复杂度:O(n^2)。

C++代码如下:

class Solution
{
public:
int minSubArrayLen(int target, vector<int>& nums)
{
int result = INT32_MAX;  //最终的结果
int sum = 0;   //子序列的数值之和
int subLength = 0; //子序列的长度
for(int i = 0; i < nums.size(); i++)  //设置子序列起点为i
{
sum = 0;
for(int j = i; j < nums.size(); j++)   //设置子序列终点位置为j
{
sum += nums[j];
if(sum >= target)   //若子序列之和超过target,更新result
{
subLength = j - i + 1;  //子序列长度
result = result < subLength ? result : subLength;
break;   //因为找的是符合条件的最短的子序列,所以符合条件后子序列没必要继续累加了。所以弹出该循环去更新子序列的起点找新的符合条件的子序列。
}
}
}
return result == INT32_MAX ? 0 : result;
}
};

思考:

使用滑动窗口,其实我把它也理解成是双指针法(快慢指针法)。

在上面的暴力法中,是一个for循环为滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环完成了一个不断搜索区间的过程。

我用双指针法在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:指向子序列的终点位置

  • 慢指针:指向子序列的起始位置

每次fastIndex移动时,都会把子序列的数值累加起来与target比较,若小于target,则进入下一个循环,fastIndex继续移动,寻找符合条件的子序列;

当子序列的数值累加后大于等于target,即符合条件,计算当前子序列的长度,并与result比较,把较小的更新为最新的result。更新result之后子序列数值之和还要减去slowIndex指向的数值,并向前移动slowIndex,因为我们要寻找符合条件的最短的子序列:1.如果不移动slowIndex而是继续移动fastIndex,就没必要了,因为后面的子序列肯定比当前的要长;2.同时,有可能减去当前slowIndex指向的数值后的子序列仍旧符合条件,所以,在找到符合条件的子序列后要移动slowIndex,更新子序列再继续判断是否符合条件。

C++代码如下:

class Solution
{
public:
int minSubArrayLen(int target, vector<int>& nums)
{
int sum = 0;  //子序列元素之和
int slowIndex = 0;
int fastIndex = 0;
int subLength = 0;   //子序列长度
int result = INT32_MAX;
for(fastIndex = 0; fastIndex < nums.size(); fastIndex++)
{
sum += nums[fastIndex];
while(sum >= target)
{
subLength = fastIndex - slowIndex + 1;
result = result < subLength ? result : subLength;
sum -= nums[slowIndex];
slowIndex++;
}
if((fastIndex==nums.size()-1)&&(slowIndex==0)&&(sum < target))   //如果整个数组都加起来也小于target,则直接返回0。
{
result = 0;
}
}
return result;
}
};

LeetCode59. 螺旋矩阵II

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/

思路:一开始的想法是把n=1~5全部列出来,再找规律,但是后来没有写出来。现做法就是模拟过程,一步一步写出来。

模拟顺时针画矩阵的过程:

  • 填充上行从左到右

  • 填充右列从上到下

  • 填充下行从右到左

  • 填充左列从下到上

由外向内一圈圈画下去。

代码中画的每一条边,都按照左闭右开的原则:

这里每一种颜色,代表一条边,可以看到每一个拐角处的处理规则,拐角处让给新的一条边来继续画,此处都是按照左闭右开的原则。

C++代码如下:

class Solution
{
public:
vector<vector<int>> generateMatrix(int n)
{
vector<vector<int>> res(n, vector<int>(n, 0));   //使用vector定义一个二维数组,vector<int>(n, 0)指初始化一个vector<int>类型数组,容量为n,初始值为0
int startx = 0, starty = 0;  //定义每循环一个圈的起始位置
int loop = n / 2;  //每个圈循环几次,例如n为奇数3,那么loop = 1只是循环一圈,矩阵中间的值需要单独处理
int mid = n / 2;   //矩阵中间的位置,例如:n为3,中间的位置就是(1,1), n为5,中间的位置就是(2,2)
int count = 1;     //用来给矩阵中每一个空格赋值
int offset = 1;    //需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i, j;
while(loop--)
{
i = startx;
j = starty;
//下面开始的四个for就是模拟转了一圈
//模拟填充上行从左到右(左闭右开)
for(j = starty; j < n - offset; j++)
{
res[startx][j] = count;
count++;
}
//模拟填充右列从上到下(左闭右开)
for(i = startx; i < n - offset; i++)
{
res[i][j] = count;
count++;
}
//模拟填充下行从右到左(左闭右开)
for(; j > starty; j--)
{
res[i][j] = count;
count++;
}
//模拟填充左列从下到上(左闭右开)
for(; i > startx; i--)
{
res[i][j] = count;
count++;
}
//第二圈开始的时候,起始位置要各自加1,例如:第一圈起始位置是(0,0),第二圈起始位置是(1,1)
startx++;
starty++;
//offset 控制每一圈里每一条边遍历的长度
offset += 1;
}
//如果n为奇数,需要单独给矩阵最中间的位置赋值
if(n % 2)
{
res[mid][mid] = count;
}
return res;
}
};

今日总结:螺旋矩阵不熟,要多练习。长度最小的子数组这题,倒是想到了用双指针法,后续可再回顾。

代码随想录算法训练营Day02 | LeetCode977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II相关推荐

  1. 随想录一期 day2 [977.有序数组的平方|209. 长度最小的子数组|59.螺旋矩阵II(剥洋葱)]

    977.有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 思路 递增数组,平方后最大值一定在最左侧或者最右侧,可想到– ...

  2. 977. 有序数组的平方|209. 长度最小的子数组|59. 螺旋矩阵 II

    977. 有序数组的平方 原理 准备:双指针.一个空数组.双指针指向的两个元素作比较,更大的数平方之后,放入空数组的尾部空位. 图解 其实这题的指针有两种方法: 从两边向中间靠拢,得到的是由大到小的值 ...

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

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

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

    day2 | LeetCode977.有序数组的平方.209.长度最小的子数组.59.螺旋矩阵II 创建时间: October 13, 2022 3:29 PM 一.今日任务 977.有序数组的平方 ...

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

    代码随想录算法训练营第二天 | LeetCode977.有序数组的平方 ,209.长度最小的子数组,59.螺旋矩阵II 一. LeetCode977.有序数组的平方 1. 题目链接[LeetCode9 ...

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

    代码随想录算法训练营第二天 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II 977.有序数组的平方 题目链接:有序数组的平方 题目描述: 给你一个按 非递减顺序 排序的整 ...

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

    第一章数组 (今日任务) 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结 建议大家先独立做题,然后看视频讲解,然后看文章讲解,然后在重新做一遍题,把题目AC,最后整理 ...

  8. _42LeetCode代码随想录算法训练营第四十二天-动态规划 | 121.买卖股票的最佳时机、122.买卖股票的最佳时机II

    _42LeetCode代码随想录算法训练营第四十二天-动态规划 | 121.买卖股票的最佳时机.122.买卖股票的最佳时机II 题目列表 121.买卖股票的最佳时机 122.买卖股票的最佳时机II 1 ...

  9. 【Leetcode数组--子数组--滑动窗口】209. 长度最小的子数组 904. 水果成篮 1004. 最大连续1的个数 III 76. 最小覆盖子串(有数组操作中重要的方法:滑动窗口!!!!)

    文章目录 Leetcode209 1.问题描述 2.解决方案 解法一:两个错误思路的算法 解法二:暴力 解法三:滑动窗口法(O(n)) Leetcode904 1.问题描述 2.解决方案 Leetco ...

最新文章

  1. java的知识点运用_Java--知识点运用
  2. 到2026年,非洲数据中心市场规模将达到50亿美元
  3. matlab 电气系统设计,MATLAB 简化了控制系统的设计和分析
  4. 10taskkill无法终止进程_?进程的状态转换
  5. 计算机的病毒防治教案,计算机病毒及其防治教案.doc
  6. fixture.detectChange开始单步调试,如何执行到Directive的ngOnChange钩子
  7. 信息学奥赛一本通 2039:【例5.6】冒泡排序
  8. Axiomatic Set Theory
  9. filter过滤后重新添加_Kibana基本使用---使用Flight Dashboard过滤数据
  10. python3数据结构菜鸟教程_Python3
  11. Spring BeanFactory、ApplicationContext IOC 容器获取与使用
  12. Linux/Aix日常报错整理
  13. element-ui自定义手机号的验证
  14. 计算机组成原理 - 基本概念
  15. php1108脱机使用,电脑打印机脱机怎么重新连接
  16. ManualResetEvent类的用法
  17. 计算机输入法知识讲解,第一讲计算机基础知识及微软拼音输入法
  18. HTML是什么?有什么作用?
  19. 利用win10笔记本自带Camera玩人脸识别
  20. 人们把使用计算机的能力和人生成功,等量齐观的意思

热门文章

  1. 美团饿了么外卖返利app定制开发小程序公众号外卖CPS淘客返利系统
  2. 图像分类经典卷积神经网络—ResNet论文翻译(纯中文版)—Deep Residual Learning for Image Recognition(深度残差学习的图像识别)
  3. linux自动挂载fcoe存储,刀箱服务器上部署集群模式CloudOS挂载FCoE存储方法
  4. 【用连续自然数之和来表达整数】
  5. 面试时计算机专业兴趣爱好,单招面试时常见问题答疑
  6. 计算机组成原理地址码方案,计算机组成原理课后习题及答案_唐朔飞7-8.pptx
  7. github 报错提示 ERROR: You‘re using an RSA key with SHA-1
  8. matlab做能耗制动,能耗制动matlab仿真.docx
  9. excel截取字符串
  10. Android studio打包app(打包后app即可分享给其他人正常安装)