代碼隨想錄算法訓練營|第六十一天|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++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C++打印 vector的几种方法小结

《C++打印vector的几种方法小结》本文介绍了C++中遍历vector的几种方法,包括使用迭代器、auto关键字、typedef、计数器以及C++11引入的范围基础循环,具有一定的参考价值,感兴... 目录1. 使用迭代器2. 使用 auto (C++11) / typedef / type alias

C++ scoped_ptr 和 unique_ptr对比分析

《C++scoped_ptr和unique_ptr对比分析》本文介绍了C++中的`scoped_ptr`和`unique_ptr`,详细比较了它们的特性、使用场景以及现代C++推荐的使用`uni... 目录1. scoped_ptr基本特性主要特点2. unique_ptr基本用法3. 主要区别对比4. u

C++11中的包装器实战案例

《C++11中的包装器实战案例》本文给大家介绍C++11中的包装器实战案例,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录引言1.std::function1.1.什么是std::function1.2.核心用法1.2.1.包装普通函数1.2.

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js

C++ 多态性实战之何时使用 virtual 和 override的问题解析

《C++多态性实战之何时使用virtual和override的问题解析》在面向对象编程中,多态是一个核心概念,很多开发者在遇到override编译错误时,不清楚是否需要将基类函数声明为virt... 目录C++ 多态性实战:何时使用 virtual 和 override?引言问题场景判断是否需要多态的三个关

C++简单日志系统实现代码示例

《C++简单日志系统实现代码示例》日志系统是成熟软件中的一个重要组成部分,其记录软件的使用和运行行为,方便事后进行故障分析、数据统计等,:本文主要介绍C++简单日志系统实现的相关资料,文中通过代码... 目录前言Util.hppLevel.hppLogMsg.hppFormat.hppSink.hppBuf