力扣hot100:739. 每日温度/54. 螺旋矩阵

2024-06-10 04:12

本文主要是介绍力扣hot100:739. 每日温度/54. 螺旋矩阵,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、 739. 每日温度
  • 二、54. 螺旋矩阵
    • 1、模拟螺旋矩阵的路径
    • 2、按层模拟

一、 739. 每日温度

LeetCode:739. 每日温度
在这里插入图片描述
经典单调栈问题,求下一个更大的数。

  • 使用单调递减栈,一个元素A出栈,当且仅当它第一次出现比它更大的数B,由于栈是单调递减的,因此该数B入栈时,会弹出这个栈中比它小的数A,A也同时找到了它的下一个更大的数。
  • 时间复杂度: O ( n ) O(n) O(n),每个元素最多入栈一次,出栈一次
  • 空间复杂度: O ( n ) O(n) O(n)
class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {stack<int> sta;int n = temperatures.size();vector<int> result(n, 0);for(int i = 0; i < n; ++ i){while(!sta.empty() && temperatures[sta.top()] < temperatures[i]){//维护单调递减的单调栈result[sta.top()] = i - sta.top();sta.pop();}sta.push(i);}return result;}
};

二、54. 螺旋矩阵

LeetCode:54. 螺旋矩阵
在这里插入图片描述

1、模拟螺旋矩阵的路径

由于没有说需要不改变矩阵中的值,我们可以直接按螺旋顺序遍历螺旋矩阵,然后在原矩阵中直接标记被遍历的位置。
注意事项:

  • matrix[x][y],在图形上,这里的x是行号,y是列好,这和数学里面的有所不同,需要区分。
  • 在矩阵遍历过程中一定要注意的两个边界值:
    • 超过数组最大边界,即pos >= size
    • 小于数组最小边界,即pos < 0

时间复杂度: O ( m n ) O(mn) O(mn)mn是矩阵大小
空间复杂度: O ( 1 ) O(1) O(1),不包括返回的答案vector

在这里插入图片描述

以下是保存(x,y)的方式遍历的方法:

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {vector<int> ans;int m = matrix.size();int n = matrix[0].size();int total_size = m * n;int x = 0, y = 0;while(ans.size() < total_size)//遍历四个方向for(int j = 0; j < 4; ++ j){int temp_x = x;//(x,y)维护下一次要遍历的起始点,(temp_x,temp_y)表示当前要遍历的点int temp_y = y;//单方向一直走while(temp_x < m && temp_y < n && temp_x >= 0 && temp_y >= 0 && matrix[temp_x][temp_y] != INT_MAX){//维护x,y的下次起点值x = temp_x + dx[(j + 1) % 4];y = temp_y + dy[(j + 1) % 4];//保存当前值ans.emplace_back(matrix[temp_x][temp_y]);//标记当前位置//cout << ans.back() << endl;matrix[temp_x][temp_y] = INT_MAX;//更新下一个遍历的位置temp_x = temp_x + dx[j];temp_y = temp_y + dy[j];}}return ans;}
private:int dx[4] = {0, 1, 0, -1};int dy[4] = {1, 0, -1, 0};//右,下,左,上的顺序 
};

以下是直接遍历的方法:

  • 由于下一次遍历的位置,只跟当前方向有关,因此为了满足每一次方向都是正确的,都能够找到一个正确位置,我们只需要每一次更新下一次遍历位置之前,都判断方向是否需要更改就行!
  • 这个方法更简单,更容易思考,而且上面那个方法,每走一次要判断是否该方向能走,和下面这个方法每走一次判断是否需要更改方向是同样的操作,但下面却利用这一操作更改成正确的方向更简洁。
class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {vector<int> ans;int m = matrix.size();int n = matrix[0].size();int total_size = m * n;int x = 0, y = 0;int direction = 0;while(ans.size() < total_size){//保存遍历结点ans.emplace_back(matrix[x][y]);matrix[x][y] = INT_MAX;//判断原始的下一次方向int new_x = x + dx[direction];int new_y = y + dy[direction];//判断下一次是否需要更改方向if(new_x < 0 || new_x >=m || new_y < 0 || new_y >=n || matrix[new_x][new_y] == INT_MAX){direction = (direction + 1) % 4;}//更新到下一次遍历位置x = x + dx[direction];y = y + dy[direction];}return ans;}
private:int dx[4] = {0, 1, 0, -1};int dy[4] = {1, 0, -1, 0};//右,下,左,上的顺序 
};

如果需要原地进行,空间复杂度且需要是 O ( 1 ) O(1) O(1),则需要进行层序遍历。

2、按层模拟

矩阵,从外到内分层,则有每次都是转一圈。
如果我们记住四个顶点,则我们就有足够信息可以使得我们无差错的转一圈。并且转完这一圈,四个顶点更新为内层的四个顶点是非常简单的。

时间复杂度: O ( m n ) O(mn) O(mn)mn是矩阵大小
空间复杂度: O ( 1 ) O(1) O(1)

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {if (matrix.size() == 0 || matrix[0].size() == 0) {return {};}int rows = matrix.size(), columns = matrix[0].size();vector<int> order;int left = 0, right = columns - 1, top = 0, bottom = rows - 1;while (left <= right && top <= bottom) {for (int column = left; column <= right; column++) {order.push_back(matrix[top][column]);}for (int row = top + 1; row <= bottom; row++) {order.push_back(matrix[row][right]);}if (left < right && top < bottom) {for (int column = right - 1; column > left; column--) {order.push_back(matrix[bottom][column]);}for (int row = bottom; row > top; row--) {order.push_back(matrix[row][left]);}}left++;right--;top++;bottom--;}return order;}
};

这篇关于力扣hot100:739. 每日温度/54. 螺旋矩阵的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1047185

相关文章

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

两数之和--力扣1

两数之和 题目思路C++代码 题目 思路 根据题目要求,元素不能重复且不需要排序,我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中,使用目标值减去当前循环的nums[i],得到差值,如果我们在map中能够找到这个差值,就说明存在两个整数的和为目标值。 如果没有找到,就将当前循环的nums[i]以及下标i放入map中,以便后续查

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

力扣第347题 前K个高频元素

前言 记录一下刷题历程 力扣第347题 前K个高频元素 前K个高频元素 原题目: 分析 我们首先使用哈希表来统计数字出现的频率,然后我们使用一个桶排序。我们首先定义一个长度为n+1的数组,对于下图这个示例就是长度为7的数组。为什么需要一个长度为n+1的数组呢?假如说总共有三个数字都为1,那么我们需要把这个1放在数组下标为3的位置,假如说数组长度为n,对于这个例子就是长度为3,那么它的

线性代数|机器学习-P35距离矩阵和普鲁克问题

文章目录 1. 距离矩阵2. 正交普鲁克问题3. 实例说明 1. 距离矩阵 假设有三个点 x 1 , x 2 , x 3 x_1,x_2,x_3 x1​,x2​,x3​,三个点距离如下: ∣ ∣ x 1 − x 2 ∣ ∣ 2 = 1 , ∣ ∣ x 2 − x 3 ∣ ∣ 2 = 1 , ∣ ∣ x 1 − x 3 ∣ ∣ 2 = 6 \begin{equation} ||x

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis