2024-03-15 leetcode寫題記錄

FlyingLight發表於2024-03-15

目錄
  • 2024-03-15 leetcode寫題記錄
    • 32. 最長有效括號
      • 題目連結
      • 題意
      • 解法
    • 42. 接雨水
      • 題目連結
      • 題意
      • 解法
        • 動態規劃
        • 雙指標

2024-03-15 leetcode寫題記錄

32. 最長有效括號

題目連結

32. 最長有效括號

題意

給你一個只包含$ '\((\)' 和 '\()\)' 的字串,找出最長有效(格式正確且連續)括號子串的長度。

解法

動態規劃

\(dp[i]\)代表從第\(i\)個字串開始,最多往前多少個字元是合法的。那麼當我們遍歷\(s\)時,第\(i\)個字元只需要跟第\(i-dp[i-1]-1\)(這裡為了方便,記為\(l\))處的字元比較。

\(l<=0\)時,代表沒有字元能夠跟第\(i\)個字元配對了,顯然\(dp[i]=0\);當第\(i\)個字元為'\((\)'時,由於第\(i\)個字元無法配對(右邊沒有字元了),所以\(dp[i]=0\);當第\(l\)個字元為'\()\)'時,由於從第\(l+1\)到第\(i-1\)的字元都已經合法了,而第\(i\)個字元無法與第\(l\)個字元配對,所以也有\(dp[i]=0\)

只有當第\(l\)個字元為'\((\)'且第\(i\)個字元為'\()\)'時,才能完成狀態轉移,方程為\(dp[i]=dp[i-1]+2+dp[l-1]\)

從所有\(dp[i]\)裡找到最大的那個,就是答案。

class Solution {
public:
    int longestValidParentheses(string s) {
        int n = s.size(), ans = 0;
        vector<int> dp(n + 1, 0);
        for (int i = 1; i <= n; ++i) {
            int l = i - dp[i - 1] - 1;
            if (l <= 0 || s[i - 1] == '(' || s[l - 1] == ')')
                continue;
            dp[i] = dp[i - 1] + 2 + dp[l - 1];
            ans = max(ans, dp[i]);
        }
        return ans;
    }
};

42. 接雨水

題目連結

42. 接雨水

題意

給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。

image

解法

動態規劃

時間複雜度\(O(n)\),空間複雜度\(O(n)\)

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        vector<int> l(n + 2, 0), r(n + 2, 0);
        for (int i = 1; i <= n; ++i) 
            l[i] = max(l[i - 1], height[i - 1]);
        for (int i = n; i >= 1; --i) 
            r[i] = max(r[i + 1], height[i - 1]);
        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            int lr = min(l[i - 1], r[i + 1]);
            if (lr <= height[i - 1])
                continue;
            ans += lr - height[i - 1];
        }
        return ans;
    }
};

雙指標

\(l\)\(r\)遍歷,若\(l\)左邊的最大值已經小於\(r\)右邊的最大值,那麼\(l\)左邊的最大值一定小於\(l+1\)右邊的最大值,所以就可以把第\(l+1\)個元素的貢獻加上,然後\(l\)右移\(1\)位,反之同理。

時間複雜度\(O(n)\),空間複雜度\(O(1)\)

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size(), l = 0, r = n - 1, ans = 0, ml = 0, mr = 0;
        while(l < r) {
            ml = max(ml, height[l]);
            mr = max(mr, height[r]);
            if (ml < mr) {
                if (ml > height[l + 1])
                    ans += ml - height[l + 1];
                l++;
            } else {
                if (mr > height[r - 1])
                    ans += mr - height[r - 1];
                r--;
            }
        }
        return ans;
    }
};

相關文章