代碼隨想錄算法訓練營|第六十天|739. 每日温度、496.下一个更大元素 I。刷题心得(c++)

目录

讀題

739. 每日温度

自己看到题目的第一想法

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

496.下一个更大元素 I

自己看到题目的第一想法

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

739. 每日温度 - 實作

思路

Code

清晰版

精簡版

496.下一个更大元素 I - 實作

思路

原思路

代碼隨想錄思路

Code

原思路

代碼隨想錄思路

總結

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

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

相關資料

739. 每日温度

496.下一个更大元素 I


讀題

739. 每日温度

自己看到题目的第一想法

就是用每個數去遍歷後面的數,但超時了,程式碼如下。

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> highTemp(temperatures.size(), 0);
        for(int i = 0; i < temperatures.size(); i++) {
            int high = 0;
            highTemp[i] = high;
            for(int j = i + 1; j < temperatures.size();j++) {
                if(temperatures[i] > temperatures[j]) high++;
                else {
                    high++;
                    highTemp[i] = high;
                    break;
                }
            }
        }
        return highTemp;
    }
};

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

單調棧,就是當要尋找一個元素左邊或者右邊第一個比自己大的元素位置,就可以考慮使用單調棧。

其本質是使用空間換時間,在遍歷的過程中使用棧來記錄右邊比當前元素高或低,優點就是数組只需要遍歷一次

使用單調棧時需要明確

  1. 單調棧裡存放的元素是甚麼
  2. 單調棧是遞增還是遞減,(順序方面因人而異,以我來說,就是跟著卡哥的順序,從棧頂到棧底,逐步遞增或遞減)

每日溫度就是一個單調棧很經典的題目,右邊第一個比自己大的元素在甚麼時候。

單調棧存放的元素是數組下標,方便在results数組中進行計算。

單調棧是遞增,可以想像假設當前元素比棧頂大,為了維持單調棧,就需要pop出來,棧頂元素就是右邊第一個比較大的元素就是當前元素。

看完卡哥的講解後對於單調棧就比較清晰了。

496.下一个更大元素 I

自己看到题目的第一想法

第一瞬間其實就想到這個只是繞一個彎,一樣單調棧是放数組下標,但是在遍歷nums2的過程中,紀錄當前元素有沒有跟nums1相同的數值,如果相同,則紀錄nums2的下標為多少到result2,其他部分一樣是製作出一個右邊第一個比自己大的元素的数組result。

之後再遍歷result2的数組,將results裡面有result2的位置讀取,假設不是-1,則將result2的值,改為nums2的當下數值加上比這個元素大的數值是後面第幾個出現的。

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

看完之後才知道我想得很複雜,其實可以使用map,nums1的數值當作key,下標當作value,在遇到右邊第一個比較大的元素時,判斷nums1有沒有nums2[st.top()]的數值,如果有則將利用map快速找到nums1的對應下標使用nums2的當前元素更新results數組。之前沒有想過這樣的解法。

739. 每日温度 - 實作

思路

  1. 單調棧存放的元素

    數組下標

  2. 單調棧性質 - 遞增 (棧頂到棧底)

  3. 當 棧頂大於等於當前數值時,儲存當前数組的下標到單調棧

  4. 當 棧頂小於當前數值時,代表找到第一個比較大的元素。

    • while循環,值到棧為空或者棧頂大於等於當前數值
      • results[st.top()] = i - st.top() → st.top 是原數組下標,跟results数組是對應的,至於i - st.top() 代表棧頂的位置跟當前元素的距離為和
      • 將棧頂元素pop出來
  5. return results數組。

Code

清晰版

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        stack<int> st;
        vector<int> results(temperatures.size(), 0);
        st.push(0);
        for(int i = 1; i < temperatures.size(); i++) {
            if(temperatures[st.top()] >= temperatures[i]) {
                st.push(i);
            } else {
                while(!st.empty() && temperatures[st.top()] < temperatures[i]) {
                    results[st.top()] = i - st.top();
                    st.pop();
                }
                st.push(i);
            }
        }

        return results;
    }
};

精簡版

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

        return results;
    }
};

496.下一个更大元素 I - 實作

思路

原思路

  1. 建立兩個數組
    1. result 紀錄nums2的每個數值右邊第一個最大元素
    2. result2 紀錄 nums1 在 nums2 的位置
  2. 遍歷nums2的過程中,紀錄當前元素有沒有跟nums1相同的數值,如果相同,則紀錄nums2的下標為多少到result2
  3. 使用單調棧更新result数組
  4. 遍歷result2數組
    1. results裡面有result2的位置讀取,假設不是-1,則將result2的值,改為nums2的當下數值加上比這個元素大的數值是後面第幾個出現的
    2. 不是則更新為-1
  5. return result2數組

代碼隨想錄思路

  1. 建立map紀錄nums1的數值與下標映射關係
    1. key = nums1數值
    2. value = nums1對應下標。
  2. 遇到右邊第一個比較大的元素時
    1. 判斷map中是否有對應的nums2的棧頂下標所映射到的數值
    2. 如果有則將利用map快速找到nums1的對應下標使用nums2的當前元素更新results數組

Code

原思路

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        stack<int> st;
        vector<int> results(nums2.size(), -1);
        vector<int> results2(nums1.size(), -1);
        for(int i = 0; i < nums2.size(); i++) {
            for(int j = 0; j < nums1.size(); j++) {
                if(nums1[j] == nums2[i]) {
                    results2[j] = i;
                    break;
                }
            }
            while(!st.empty() && nums2[st.top()] < nums2[i]) {
                results[st.top()] = i - st.top();
                st.pop();
            }
            st.push(i);
        }
        for(int k = 0; k < nums1.size(); k++) {
            int temp = results2[k];
            if(results[temp] != -1) results2[k] = nums2[temp + results[temp]];
            else results2[k] = results[temp];
            
        }

        return results2;
    }
};

代碼隨想錄思路

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        stack<int> st;
        vector<int> results(nums1.size(), -1);
        unordered_map<int, int> umap;
        for (int i = 0; i < nums1.size(); i++) {
            umap[nums1[i]] = i;
        }
        for(int i = 0; i < nums2.size(); i++) {
            while(!st.empty() && nums2[st.top()] < nums2[i]) {
                if(umap.count(nums2[st.top()]) > 0) {
                    results[umap[nums2[st.top()]]] = nums2[i];
                }
                st.pop();
            }
            st.push(i);
        }

        return results;
    }
};

總結

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

第一次理解單調棧的題目,在理解上花了比較長的時間,並且自己對於map的使用不太熟悉,所以在第二題時,想到了更繞的解法。

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

今天大概學習2hr,主要是去理解單調棧的思維,理解不難,但是在實踐過程中需要多練習。

相關資料

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

739. 每日温度

https://programmercarl.com/0739.每日温度.html

496.下一个更大元素 I

https://programmercarl.com/0496.下一个更大元素I.html

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二天的算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值