代碼隨想錄算法訓練營|第六十一天|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++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

VSCode中C/C++编码乱码问题的两种解决方法

《VSCode中C/C++编码乱码问题的两种解决方法》在中国地区,Windows系统中的cmd和PowerShell默认编码是GBK,但VSCode默认使用UTF-8编码,这种编码不一致会导致在VSC... 目录问题方法一:通过 Code Runner 插件调整编码配置步骤方法二:在 PowerShell

C/C++随机数生成的五种方法

《C/C++随机数生成的五种方法》C++作为一种古老的编程语言,其随机数生成的方法已经经历了多次的变革,早期的C++版本使用的是rand()函数和RAND_MAX常量,这种方法虽然简单,但并不总是提供... 目录C/C++ 随机数生成方法1. 使用 rand() 和 srand()2. 使用 <random

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

C++ Primer 标准库vector示例详解

《C++Primer标准库vector示例详解》该文章主要介绍了C++标准库中的vector类型,包括其定义、初始化、成员函数以及常见操作,文章详细解释了如何使用vector来存储和操作对象集合,... 目录3.3标准库Vector定义和初始化vector对象通列表初始化vector对象创建指定数量的元素值

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1