代碼隨想錄算法訓練營|第六十一天|503.下一个更大元素II、42. 接雨水。刷题心得(c++)

本文主要是介绍代碼隨想錄算法訓練營|第六十一天|503.下一个更大元素II、42. 接雨水。刷题心得(c++),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

讀題

503.下一个更大元素II

看完代码随想录之后的想法

42. 接雨水

看完代码随想录之后的想法

503.下一个更大元素II - 實作

思路

Code

42. 接雨水 - 實作

思路

原思路錯誤點

雙指針縱向運算思路

單調棧橫向運算思路

Code

原思路 - 錯誤 (縱向運算)

雙指針縱向運算思路

單調棧橫向運算思路

總結

自己实现过程中遇到哪些困难

今日收获,记录一下自己的学习时长

相關資料

503.下一个更大元素II

42. 接雨水


讀題

503.下一个更大元素II

看完代码随想录之后的想法

一開始看到環形數列的時候有點矇,但是在聽完卡哥的講解後,終於理解了,原來可以使用取mod的做法來模擬環形數列,在影片講解當中,最後有提到一個問題,假設在一個遞減的數列當中,比如說是[4, 3, 2] 那環形則會變成 [4,3,2,4,3,2]對應到的result則會是[-1, 4, ,4, -1, -1] 有提到後面的值會不會覆蓋到前面,我想說的是不會,因為只有當遇到了比較大的值才會觸發更新,那3, 2唯一會碰到也只會是在第二個4才會觸發更新,假設改為[1,4,3,2,1,4,3,2] 也一樣,最終1還是會更新到他的右邊第一個最大的數值。

42. 接雨水

看完代码随想录之后的想法

我原本的思路是縱向運算,但是使用到錯誤的方法,應該是要找左邊最大的以及右邊最大的,我的作法少了這點,看完隨想錄的講解後,才豁然開朗,使用橫向運算比較直覺一點,在理解上也比較清晰,如果遇到右邊比較大的元素,那就是右節點減去當前棧頂的下一個元素,再減去1就會是中間的的寬度,高度則是棧頂的左右元素取最小的減去棧頂對應的数組,兩者相乘,加到result當中就好了,用這個思路去理解就清晰很多了。

503.下一个更大元素II - 實作

思路

  1. 單調棧存放的是數組下標
  2. 單調棧性質為遞增
  3. 將遍歷大小擴為兩倍數組大小,並將i進行取mod運算。

Code

class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {stack<int> st;vector<int> results(nums.size(), -1);for(int i = 0; i < (nums.size() * 2) ; i++) {while(!st.empty() && nums[st.top()] < nums[i % nums.size()]) {results[st.top()] = nums[i % nums.size()];st.pop();}st.push(i % nums.size());}return results;}
};

 

42. 接雨水 - 實作

思路

原思路錯誤點

原思路如果改變作法就會對了,因為是做縱向的運算,所以要找到左邊最大以及右邊最大的柱子,如果使用單調棧,則只會找到左邊以及右邊第一個比當前大的元素,而不是最大的,因此會少計算了一些面積。

雙指針縱向運算思路

  1. 使用兩個數組紀錄左邊最高以及右邊最高
  2. maxLeft 由左向右遍歷 maxLeft當前高度 max(當前高度,maxLeft前一個高度)
  3. maxRight 由右向左遍歷 maxRight當前高度 max(當前高度,maxRight前一個高度)
  4. 求和,遍歷数組,左右最高取最小,並減去當前高度
  5. 假設大於0,則加入到結果當中

單調棧橫向運算思路

  1. 單調棧存放元素為數組下標
  2. 單調棧性質為遞增
  3. 當前元素對應的数組值與棧頂元素對應的数組值比較與處理
    1. 小於
      1. 將當前元素放入棧頂
    2. 等於
      1. pop棧頂元素
      2. 將當前元素放入棧頂
      3. 因為相等的話,如果比較最小值時,當前元素與棧頂元素相減 = 0 無論如何相乘都只會是0
    3. 大於
      1. 儲存棧頂元素
      2. pop棧頂
      3. 高度是
        1. 當前元素與目前棧頂元素對應的数組數值取最小減去之前儲存棧頂元素對應的数組數值
      4. 寬度是
        1. 當前元素減去目前棧頂元素再減去1
      5. sum += h * w
      6. 儲存當前元素到單調棧中
  4. return sum.

Code

原思路 - 錯誤 (縱向運算)

class Solution {
public:int trap(vector<int>& height) {stack<int> st;vector<int> water(height.size(), 0);vector<int> leftH(height.size(), 0);int water = 0;for(int i = 0; i < height.size() ; i++) {while(!st.empty() && height[st.top()] < height[i]) {rightH[st.top()] = height[i];st.pop();}st.push(i);}while (!st.empty()) st.pop();for(int i = height.size() - 1; i >= 0; i--) {while(!st.empty() && height[st.top()] < height[i]) {leftH[st.top()] = height[i];st.pop();}st.push(i);}for(int i = 0; i < height.size(); i++) {if(min(rightH[i], leftH[i]) - height[i] >= 0)water += min(rightH[i], leftH[i]) - height[i];}return water;}
};

雙指針縱向運算思路

class Solution {
public:int trap(vector<int>& height) {vector<int> maxLeft(height.size(), 0);vector<int> maxRight(height.size(), 0);int size = height.size();maxLeft[0] = height[0];for (int i = 1; i < size; i++) {maxLeft[i] = max(height[i], maxLeft[i - 1]);}maxRight[size - 1] = height[size - 1];for (int i = size - 2; i >= 0; i--) {maxRight[i] = max(height[i], maxRight[i + 1]);}int sum = 0;for (int i = 0; i < size; i++) {int count = min(maxLeft[i], maxRight[i]) - height[i];if (count > 0) sum += count;}return sum;}
};

單調棧橫向運算思路

class Solution {
public:int trap(vector<int>& height) {stack<int> st;st.push(0);int sum = 0;for(int i = 1; i < height.size() ; i++) {if(height[st.top()] > height[i]){st.push(i);}else if(height[st.top()] == height[i]){st.pop();st.push(i);} else {while(!st.empty() && height[st.top()] < height[i]) {int mid = st.top();st.pop();if(!st.empty()) {int h = min(height[i], height[st.top()]) - height[mid];int w = i - st.top() - 1;sum += h * w;}}st.push(i);}}return sum;}
};

 

總結

自己实现过程中遇到哪些困难

困難點主要是接雨水沒有想到可以這樣利用單調棧的性質,以及自己一開始在做接雨水題目時思路想成縱向運算,看完影片後才比較知道自己為甚麼做錯了。

今日收获,记录一下自己的学习时长

今天大概學習2hr,主要是了解了如何處理環形數列以及單調棧如何在接雨水這個題目中運用

相關資料

● 今日学习的文章链接和视频链接

503.下一个更大元素II

https://programmercarl.com/0503.下一个更大元素II.html

42. 接雨水

https://programmercarl.com/0042.接雨水.html

这篇关于代碼隨想錄算法訓練營|第六十一天|503.下一个更大元素II、42. 接雨水。刷题心得(c++)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性: