LeetCode刷题,代码随想录算法训练营Day2

977.有序数组的平方

题目链接 : 977.有序数组的平方

题目思路:关键在于双指针思想的应用

  1. 输入:nums = [-4,-1,0,3,10]
  2. 输出:[0,1,9,16,100]
  3. 解释:平方后,数组变为 [16,1,0,9,100]
  4. 排序后,数组变为 [0,1,9,16,100]

暴力破解(sort方法、冒泡)

应该为一个for循环进行全部平方,直接调用sort进行排序即可,时间复杂度n+n*log2n

  1. 1 class Solution {
  2. 2 public:
  3. 3 vector<int> sortedSquares(vector<int>& nums) {
  4. 4 int i;
  5. 5 for(i=0;i<nums.size();i++){
  6. 6 nums[i]*=nums[i];
  7. 7 }
  8. 8 sort(nums.begin(),nums.end());
  9. 9 return nums;
  10. 10 }
  11. 11 };

如果使用冒泡排序时间复杂度会为n²

  1. 1 for(i=0;i<nums.size()-1;i++){
  2. 2 for(j=0;j<nums.size()-1-i;j++){
  3. 3 if(nums[j]>nums[j+1]){
  4. 4 swap(nums[j],nums[j+1]);
  5. 5 }
  6. 6 }
  7. 7 }

双指针法

和昨天的题目一样,通过双指针在一个for循环里做出两个for循环的事情。本题通过一前一后的双指针相向进行

如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。

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

  1. 1 class Solution {
  2. 2 public:
  3. 3 vector<int> sortedSquares(vector<int>& A) {
  4. 4 int k = A.size() - 1; //索引的下标
  5. 5 vector<int> result(A.size(), 0);//定义新数组
  6. 6 for (int i = 0, j = A.size() - 1; i <= j;) { //循环终止, 注意这里要i <= j,因为最后要处理两个元素
  7. 7 if (A[i] * A[i] < A[j] * A[j]) {
  8. 8 result[k--] = A[j] * A[j];
  9. 9 j--;
  10. 10 }
  11. 11 else {
  12. 12 result[k--] = A[i] * A[i];
  13. 13 i++;
  14. 14 }
  15. 15 }
  16. 16 return result;
  17. 17 }
  18. 18 };

注意:不能再i=j的时候退出,否则中间两个无法比较。

由于i++和j--是有条件的,因此for循环的最后需要空着,自增自减在条件中进行完成。

209.长度最小的子数组

题目链接:209.长度最小的子数组

解题思路:

暴力解法

  1. class Solution {
  2. public:
  3. int minSubArrayLen(int s, vector<int>& nums) {
  4. int result = INT32_MAX; // 最终的结果
  5. int sum = 0; // 子序列的数值之和
  6. int subLength = 0; // 子序列的长度
  7. for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
  8. sum = 0;
  9. for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
  10. sum += nums[j];
  11. if (sum >= s) { // 一旦发现子序列和超过了s,更新result
  12. subLength = j - i + 1; // 取子序列的长度
  13. result = result < subLength ? result : subLength;
  14. break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
  15. }
  16. }
  17. }
  18. // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
  19. return result == INT32_MAX ? 0 : result;
  20. }
  21. };

时间复杂度O(n²)

滑动窗口解法

滑动窗口即不断通过调节子序列的起始位置和最终位置,得出想要的结果

下标j应该为滑动窗口的终止位置。如果j是位于起始位置,则仍然是暴力解法。

当集合里的所有元素和大于s时再移动起始位置即可

可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。

代码实现:

  1. 1 class Solution {
  2. 2 public:
  3. 3 int minSubArrayLen(int s, vector<int>& nums) {
  4. 4 int result = INT32_MAX;
  5. 5 int sum = 0; // 滑动窗口数值之和
  6. 6 int i = 0; // 滑动窗口起始位置
  7. 7 int subLength = 0; // 滑动窗口的长度
  8. 8 for (int j = 0; j < nums.size(); j++) {
  9. 9 sum += nums[j];
  10. 10 // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
  11. 11 while (sum >= s) {
  12. 12 subLength = (j - i + 1); // 取子序列的长度
  13. 13 result = result < subLength ? result : subLength;
  14. 14 sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
  15. 15 }
  16. 16 }
  17. 17 // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
  18. 18 return result == INT32_MAX ? 0 : result;
  19. 19 }
  20. 20 };

59螺旋矩阵Ⅱ

题目链接:59螺旋矩阵Ⅱ

模拟解法

螺旋矩阵没有暴力破解,只能通过四个for循环重复实现对不同数字的输入。螺旋矩阵的重要点在于判断最后一个列的数字个数和奇数大小矩阵时的中间位置的数字。

整个矩阵的实现是由两组循环实现的,最外层是while循环,用来控制一周的整体循环,每一行通过一个for循环实现一行内的输入输出。

处理规则:循环不变量

按左闭右开的规则对各边进行遍历,都只处理第一个节点,最后一个节点不处理。

定义的i对应startx,j对应starty,二维数组中i控制行的数量,j控制列的数量,因此第一个for中就是只对j进行修改。外层修改完成后startx和starty都进行自增,内一层初始的节点位置沿对角线进行逐层深入。

每层长度通过offset进行控制,最外层就是1,每往内一层即+1

螺旋矩阵的数字输入通过count进行计数,在每个for循环内都要自增一次

  1. 1 class Solution {
  2. 2 public:
  3. 3 vector<vector<int>> generateMatrix(int n) {
  4. 4 vector<vector<int>> res(n, vector<int>(n, 0));//使用vector定义二维数组
  5. 5 int startx=0,starty=0;//定义循环一个圈的起始位置
  6. 6 short loop=n/2;//n==3时一次循环,n==4时2次循环完成
  7. 7 short mid=n/2;//中间的部分单独填充,位于中心位置
  8. 8 short count=1;//定义矩阵中每一个空格赋值,从1开始
  9. 9 short offset=1;//需要控制每一个边遍历的长度,每循环一次右边界收缩一位
  10. 10 short i,j;
  11. 11 while(loop--){
  12. 12 i=startx;
  13. 13 j=starty;
  14. 14 //四个for模拟转了一圈
  15. 15 //模拟填充上行从左到右(左闭右开)//x不变,j变化
  16. 16 for(j=starty;j<n-offset;j++){
  17. 17 res[startx][j]=count++;
  18. 18 }
  19. 19 //模拟填充右列从上到下
  20. 20 for(i=startx;i<n-offset;i++){
  21. 21 res[i][j]=count++;
  22. 22 }
  23. 23 //模拟填充下行从右到左
  24. 24 for(;j>starty;j--){
  25. 25 res[i][j]=count++;
  26. 26 }
  27. 27 for(;i>startx;i--){
  28. 28 res[i][j]=count++;
  29. 29 }
  30. 30 startx++;
  31. 31 starty++;//xy沿对角线向内移动
  32. 32 offset+=1;//offset控制每一圈里一条边遍历的长度
  33. 33 }
  34. 34 //n是奇数的话,需单独为中间的数赋值
  35. 35 if(n%2){
  36. 36 res[mid][mid]=count;
  37. 37 }
  38. 38 return res;
  39. 39 }
  40. 40 };

总结

除最后一个题目外,其他的数组题目都是对双指针思想的应用,双指针是通过指针的移动实现对一次for循环的取代,从而节约和降低时间复杂度。

由于之前没有学习过C++,现在用C++写代码有很多知识点还是比较难以理解的,现在虽然很吃力,但只要坚持就一定可以克服,加油!

代码随想录算法训练营Day2|977有序数组的平方 209.长度最小的子数组 59螺旋矩阵Ⅱ(C++)的更多相关文章

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

    977.有序数组的平方 :https://leetcode.cn/problems/squares-of-a-sorted-array/ 心得:周末再写... public class Solutio ...

  2. 领扣-209 长度最小的子数组 Minimum Size Subarray Sum MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. 代码随想录训练营day 2 |977有序数组的平方 209.长度最小的子数组 (C++)

    977.有序数组的平方 题目链接:977.有序数组的平方 题目描述:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 例子如下: 输入 ...

  4. lc.209 长度最小的子数组

    题目 给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, n ...

  5. 【LeetCode】209. 长度最小的子数组

    209. 长度最小的子数组 知识点:数组:前缀和:二分法:双指针:滑动窗口 题目描述 给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小 ...

  6. Java实现 LeetCode 209 长度最小的子数组

    209. 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = ...

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

    2022/09/22 第二天 第一题 这题我就直接平方后排序了,很无脑但很快乐啊(官方题解是双指针 第二题 滑动窗口的问题,本来我也是直接暴力求解发现在leetCode上超时,看了官方题解,也是第一次 ...

  8. Leetcode 209.长度最小的子数组 By Python

    给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums = [2, ...

  9. LeetCode 209. 长度最小的子数组(Minimum Size Subarray Sum)

    题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...

  10. LeetCode:长度最小的子数组【209】

    LeetCode:长度最小的子数组[209] 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 ...

随机推荐

  1. 使用ASP.NET CORE SignalR实现APP扫描登录

    使用signalr实现APP扫码登录 1. 背景介绍 在移动化时代,web开发很多时候都会带着移动端开发,这个时候为了减少重复输入账号密码以及安全性,很多APP端都会提供一个扫码登录功能,web端生成 ...

  2. Mysql 事务隔离级别和锁的关系

    我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于 ...

  3. 实现一个CRDT工具库——PSet

    PSet 这段代码实现了一个PSet,即Positive Set,是GSet的扩展.PSet是一个集合,支持添加和删除元素,但是不支持重复元素.PSet的实现是通过两个GSet来实现的,一个GSet存 ...

  4. 深度学习之PyTorch实战(4)——迁移学习

    (这篇博客其实很早之前就写过了,就是自己对当前学习pytorch的一个教程学习做了一个学习笔记,一直未发现,今天整理一下,发出来与前面基础形成连载,方便初学者看,但是可能部分pytorch和torch ...

  5. ASP.NET Core - 选项系统之选项验证

      就像 Web Api 接口可以对入参进行验证,避免用户传入非法的或者不符合我们预期的参数一样,选项也可以对配置源的内容进行验证,避免配置中的值与选项类中的属性不对应或者不满足预期,毕竟大部分配置都 ...

  6. Windows 11 Update Download Error Solution - 0x80248007

    I had the same issue on a Windows 2019 virtual server while performing routine windows updates. The ...

  7. Web前端开发必看的100道大厂面试题

    1. 说说gulp和webpack的区别 开放式题目 Gulp强调的是前端开发的工作流程.我们可以通过配置一系列的task,定义task处理的事务(例如文件压缩合并.雪碧图.启动server.版本控制 ...

  8. window远程桌面之通过修改端口链接

      windows开启及连接远程桌面 技术标签: 后端开发  windows         桌面 -> 此电脑 图标右键 -> 属性 远程设置 远程桌面 -> 修改为允许远程连接到 ...

  9. [Linux]Linux中安装软件的方式?

    近日处理安全漏洞时,出现了这样一个问题: 判断某软件组件是通过何种方式安装的. 知道是何种方式安装,才方便做进一步的解决(升级/配置/卸载等操作) 1 解压即用 例如: sublime_text.py ...

  10. 五月九号java基础知识点

    1.哈希集合元素不按顺序排序,若要排序使用LinkedHashSet类2.树集合类不仅实现Set接口,还实现java.lang.SortedSet接口来实现排序操作3.TreeSet<Strin ...