当前位置: 首页 > news >正文

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

目录:

解题及思路学习

977.有序数组的平方

https://leetcode.cn/problems/squares-of-a-sorted-array/submissions/

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]

思考:双指针法

class Solution {
public:vector<int> sortedSquares(vector<int>& nums) {int k = nums.size() - 1;vector<int> result(nums.size(), 0);for (int i = 0, j = k; i <= j;) {if (nums[j] * nums[j] > nums[i] * nums[i]) {result[k--] = nums[j] * nums[j];j--;} else {result[k--] = nums[i] * nums[i];i++;}}return result;}
};

时间复杂度为O(n)

空间复杂度为O(1)

209.长度最小的子数组

https://leetcode.cn/problems/minimum-size-subarray-sum/

给定一个含有 n ****个正整数的数组和一个正整数 target 

找出该数组中满足其和 ****≥ target **的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。**如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2

思考:需要找到满足和≥ target的最短子数组长度。利用双指针法,统计两个指针之间的和。当两个指针之间的数值count < target的时候,指针就一直往前移动。当 ≥ target的时候,记录下最短的距离。然后左边的指针就往右移,看是否满足。

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int result = INT32_MAX;int i = 0; int sum = 0;int sublength = 0;for (int j = 0; j < nums.size(); j++) {sum += nums[j];while(sum >= target) {sublength = (j - i + 1);result = result < sublength? result: sublength;sum -= nums[i++];}}return result == INT32_MAX ? 0 : result;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

59.螺旋矩阵II

https://leetcode.cn/problems/spiral-matrix-ii/

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:

!https://assets.leetcode.com/uploads/2020/11/13/spiraln.jpg

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

思考:这道题 就模拟题。之前我记得主要是考察边界的问题。

class Solution {
public:vector<vector<int>> generateMatrix(int n) {vector<vector<int>> res(n, vector<int>(n, 0));int startx = 0, starty = 0;int loop = n / 2;int mid = n / 2;int count = 1;int offset = 1;int i , j;while(loop--) {i = startx;j = starty;for (j = starty; j < n - offset; j++) {res[startx][j] = count++;}for (i = startx; i < n - offset; i++) {res[i][j] = count++;}for (; j > starty; j--) {res[i][j] = count++;}for (; i > startx; i--) {res[i][j] = count++;}startx++;starty++;offset += 1;}if (n % 2) {res[mid][mid] = count;}return res;}};
  • 时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
  • 空间复杂度 O(1)

扩展题目

904. 水果成篮

你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

  • 你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
  • 你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
  • 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。

给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。

示例 2:

输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。

思考:水果篮只能装单一类型水果。这道题可以抽象一下,最多只能有两种不同的数据,问最多的nums范围。可以用双指针法,在两个指针的中间最多只能有两种数据。遇到另一种数据则停止。可以用一个map来记录。

解题:

我们用哈希表 cntcntcnt 维护当前窗口内的水果种类以及对应的数量,用双指针 jjj 和 iii 维护窗口的左右边界。

遍历数组 fruits,将当前水果 xxx 加入窗口,即 cnt[x]++cnt[x]++cnt[x]++,然后判断当前窗口内的水果种类是否超过了 222 种,如果超过了 222 种,就需要将窗口的左边界 jjj 右移,直到窗口内的水果种类不超过 222 种为止。然后更新答案,即 ans=max⁡(ans,i−j+1)ans = \max(ans, i - j + 1)ans=max(ans,i−j+1)。

遍历结束后,即可得到最终的答案。

class Solution {
public:int totalFruit(vector<int>& fruits) {unordered_map<int, int> umap;int result = 0;for (int i = 0, j = 0; i < fruits.size(); i++) {umap[fruits[i]]++;                            //记录水果种类及数量while(umap.size() > 2) {int temp = fruits[j++];if (--umap[temp] == 0) umap.erase(temp);  // 当水果数量为0的时候,就可以将其擦除了}result = max(result, i - j + 1);}return result;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。

思考:用一个unordered_map 哈希表来记录t中所有字符的出现次数。然后用双指针在s中寻找满足条件的子串。

解题:两个哈希表,hs哈希表维护的是s字符串中滑动窗口中各个字符出现多少次,ht哈希表维护的是t字符串各个字符出现多少次。如果hs哈希表中包含ht哈希表中的所有字符,并且对应的个数都不小于ht哈希表中各个字符的个数,那么说明当前的窗口是可行的,可行中的长度最短的滑动窗口就是答案。

过程如下:

1、遍历t字符串,用ht哈希表记录t字符串各个字符出现的次数。

2、定义两个指针j和i,j指针用于收缩窗口,i指针用于延伸窗口,则区间[j,i]表示当前滑动窗口。首先让i和j指针都指向字符串s开头,然后枚举整个字符串s ,枚举过程中,不断增加i使滑动窗口增大,相当于向右扩展滑动窗口。

3、每次向右扩展滑动窗口一步,将s[i]加入滑动窗口中,而新加入了s[i],相当于滑动窗口维护的字符数加一,即hs[s[i]]++

4、对于新加入的字符s[i],如果hs[s[i]] <= ht[s[i]],说明当前新加入的字符s[i]是必需的,且还未到达字符串t所要求的数量。我们还需要事先定义一个cnt变量, cnt维护的是s字符串[j,i]区间中满足t字符串的元素的个数,记录相对应字符的总数。新加入的字符s[i]必需,则cnt++。

5、我们向右扩展滑动窗口的同时也不能忘记收缩滑动窗口。因此当hs[s[j]] > ht[s[j]时,说明hs哈希表中s[j]的数量多于ht哈希表中s[j]的数量,此时我们就需要向右收缩滑动窗口,j++并使hs[s[j]]–,即hs[s[j ++ ]] --。

6、当cnt == t.size时,说明此时滑动窗口包含符串 t 的全部字符。我们重复上述过程找到最小窗口即为答案。

class Solution {
public:string minWindow(string s, string t) {unordered_map<char, int> hs, ht;for (auto c: t) ht[c]++;string result;int count = 0;for (int i = 0, j = 0; i < s.size(); i++) {hs[s[i]]++; if (hs[s[i]] <= ht[s[i]]) count++;     //记录必须加入的字符长度while(hs[s[j]] > ht[s[j]]) hs[s[j++]]--;      // 右移j,并将hs中的计数-1if (count == t.size()) {      //当包含了t中所有的字符if (result.empty() || i - j + 1 < result.size()) result = s.substr(j, i - j + 1);      //分割子字符串}}return result;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

54. 螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

!https://assets.leetcode.com/uploads/2020/11/13/spiral1.jpg

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

思考:这道题也是一道模拟题,主要考察对代码的掌控能力。

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {vector<int> result;if (matrix.empty()) return result;int u = 0;int d = matrix.size() - 1;int l = 0;int r = matrix[0].size() - 1;while (true) {for (int i = l; i <= r; i++) result.push_back(matrix[u][i]);if (++ u > d) break;for (int i = u; i <= d; i++) result.push_back(matrix[i][r]);if (-- r < l) break;for (int i = r; i >= l; i--) result.push_back(matrix[d][i]);if (--d < u) break;for (int i = d; i >= u; i--) result.push_back(matrix[i][l]);if (++l > r) break;}return result;}
};

复盘总结

个人反思

双指针方法yyds

模拟题的话只能是找到规律来做了。

http://www.lryc.cn/news/107164.html

相关文章:

  • 【力扣每日一题】2023.8.2 翻转卡片游戏
  • IDEA设置中文 中文插件
  • Python——调用webdriver.Chrome() 报错
  • 人工智能发展的五个主要技术方向是什么?
  • 机器学习知识经验分享之六:决策树
  • 回归预测 | MATLAB实现SO-CNN-GRU蛇群算法优化卷积门控循环单元多输入单输出回归预测
  • 309. 买卖股票的最佳时机含冷冻期
  • P1119 灾后重建
  • USB采集卡如何打pts
  • 机器学习实战13-超导体材料的临界温度预测与分析(决策树回归,梯度提升回归,随机森林回归和Bagging回归)
  • 小研究 - 一种复杂微服务系统异常行为分析与定位算法(二)
  • Docker 安装 MySQL5.6
  • vue组件跳层级时的事件处理 (事件的广播与派发)
  • 毫米波雷达 TI IWR6843 官方测试程序(Out Of Box Demo)
  • 中大标了 5813万
  • Java电子招投标采购系统源码-适合于招标代理、政府采购、企业采购、等业务的企业 tbms
  • RocketMQ安装和简单使用
  • Codeforces Round 869 (Div. 2)
  • 【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 3
  • CTFSHOW php 特性
  • 2、认识O(nlogn)的排序
  • 什么是 HTTP 长轮询?
  • 操作系统用户态和核心态和CPU上下文切换
  • TSINGSEE青犀视频汇聚平台EasyCVR视频广场面包屑侧边栏支持拖拽操作
  • RocketMQ发送消息超时异常
  • WordPress做权重站:二级目录伪静态写法
  • 浅谈下API初步认知
  • LeetCode--剑指Offer75(2)
  • 基于vue-cli3的vue项目 通过postcss-pxtorem 实现px自动转换成rem并解决版本问题
  • 前端开发常用的方法封装(二)