欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實現(xiàn)LeetCode(32.最長有效括號)

 更新時間:2021年07月14日 11:21:50   作者:Grandyang  
這篇文章主要介紹了C++實現(xiàn)LeetCode(32.最長有效括號),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下

[LeetCode] 32. Longest Valid Parentheses 最長有效括號

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

Example 1:

Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"

這道求最長有效括號比之前那道 Valid Parentheses 難度要大一些,這里還是借助棧來求解,需要定義個 start 變量來記錄合法括號串的起始位置,遍歷字符串,如果遇到左括號,則將當前下標壓入棧,如果遇到右括號,如果當前棧為空,則將下一個坐標位置記錄到 start,如果棧不為空,則將棧頂元素取出,此時若棧為空,則更新結(jié)果和 i - start + 1 中的較大值,否則更新結(jié)果和 i - st.top() 中的較大值,參見代碼如下:

解法一:

class Solution {
public:
    int longestValidParentheses(string s) {
        int res = 0, start = 0, n = s.size();
        stack<int> st;
        for (int i = 0; i < n; ++i) {
            if (s[i] == '(') st.push(i);
            else if (s[i] == ')') {
                if (st.empty()) start = i + 1;
                else {
                    st.pop();
                    res = st.empty() ? max(res, i - start + 1) : max(res, i - st.top());
                }
            }
        }
        return res;
    }
};

還有一種利用動態(tài)規(guī)劃 Dynamic Programming 的解法。這里使用一個一維 dp 數(shù)組,其中 dp[i] 表示以 s[i-1] 結(jié)尾的最長有效括號長度(注意這里沒有對應 s[i],是為了避免取 dp[i-1] 時越界從而讓 dp 數(shù)組的長度加了1),s[i-1] 此時必須是有效括號的一部分,那么只要 dp[i] 為正數(shù)的話,說明 s[i-1] 一定是右括號,因為有效括號必須是閉合的。當括號有重合時,比如 "(())",會出現(xiàn)多個右括號相連,此時更新最外邊的右括號的 dp[i] 時是需要前一個右括號的值 dp[i-1],因為假如 dp[i-1] 為正數(shù),說明此位置往前 dp[i-1] 個字符組成的子串都是合法的子串,需要再看前面一個位置,假如是左括號,說明在 dp[i-1] 的基礎上又增加了一個合法的括號,所以長度加上2。但此時還可能出現(xiàn)的情況是,前面的左括號前面還有合法括號,比如 "()(())",此時更新最后面的右括號的時候,知道第二個右括號的 dp 值是2,那么最后一個右括號的 dp 值不僅是第二個括號的 dp 值再加2,還可以連到第一個右括號的 dp 值,整個最長的有效括號長度是6。所以在更新當前右括號的 dp 值時,首先要計算出第一個右括號的位置,通過 i-3-dp[i-1] 來獲得,由于這里定義的 dp[i] 對應的是字符 s[i-1],所以需要再加1,變成 j = i-2-dp[i-1],這樣若當前字符 s[i-1] 是左括號,或者j小于0(說明沒有對應的左括號),或者 s[j] 是右括號,此時將 dp[i] 重置為0,否則就用 dp[i-1] + 2 + dp[j] 來更新 dp[i]。這里由于進行了 padding,可能對應關系會比較暈,大家可以自行帶個例子一步一步執(zhí)行,應該是不難理解的,參見代碼如下:

解法二:

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

此題還有一種不用額外空間的解法,使用了兩個變量 left 和 right,分別用來記錄到當前位置時左括號和右括號的出現(xiàn)次數(shù),當遇到左括號時,left 自增1,右括號時 right 自增1。對于最長有效的括號的子串,一定是左括號等于右括號的情況,此時就可以更新結(jié)果 res 了,一旦右括號數(shù)量超過左括號數(shù)量了,說明當前位置不能組成合法括號子串,left 和 right 重置為0。但是對于這種情況 "(()" 時,在遍歷結(jié)束時左右子括號數(shù)都不相等,此時沒法更新結(jié)果 res,但其實正確答案是2,怎么處理這種情況呢?答案是再反向遍歷一遍,采取類似的機制,稍有不同的是此時若 left 大于 right 了,則重置0,這樣就可以 cover 所有的情況了,參見代碼如下:

解法三:

class Solution {
public:
    int longestValidParentheses(string s) {
        int res = 0, left = 0, right = 0, n = s.size();
        for (int i = 0; i < n; ++i) {
            (s[i] == '(') ? ++left : ++right;
            if (left == right) res = max(res, 2 * right);
            else if (right > left) left = right = 0;
        }
        left = right = 0;
        for (int i = n - 1; i >= 0; --i) {
            (s[i] == '(') ? ++left : ++right;
            if (left == right) res = max(res, 2 * left);
            else if (left > right) left = right = 0;
        }
        return res;
    }
};

到此這篇關于C++實現(xiàn)LeetCode(32.最長有效括號)的文章就介紹到這了,更多相關C++實現(xiàn)最長有效括號內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言獲取數(shù)組長度的幾種方法

    C語言獲取數(shù)組長度的幾種方法

    這篇文章主要介紹了C語言獲取數(shù)組長度的幾種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • C++實現(xiàn)將內(nèi)容寫入文件的方法總結(jié)

    C++實現(xiàn)將內(nèi)容寫入文件的方法總結(jié)

    本文主要總結(jié)了一下C/C++將內(nèi)容寫入文件的方法,C的方法有些單調(diào),畢竟沒有庫函數(shù)。C++則豐富些,下面我把搜集到的整理一下,供大家參考
    2023-04-04
  • C語言main函數(shù)的參數(shù)及其返回值詳細解析

    C語言main函數(shù)的參數(shù)及其返回值詳細解析

    main函數(shù)的返回值用于說明程序的退出狀態(tài)。如果返回0,則代表程序正常退出;返回其它數(shù)字的含義則由系統(tǒng)決定。通常,返回非零代表程序異常退出
    2013-10-10
  • 詳解C語言中雙向循環(huán)鏈表的實現(xiàn)

    詳解C語言中雙向循環(huán)鏈表的實現(xiàn)

    雙向鏈表也叫雙鏈表,是鏈表的一種,它的每個數(shù)據(jù)結(jié)點中都有兩個指針,分別指向直接后繼和直接前驅(qū)。本文將用C語言實現(xiàn)雙向循環(huán)鏈表,需要的可以參考一下
    2022-06-06
  • C++模板元編程實現(xiàn)選擇排序

    C++模板元編程實現(xiàn)選擇排序

    這篇文章主要介紹了C++模板元編程實現(xiàn)選擇排序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • 使用c++實現(xiàn)OpenCV繪制圓端矩形

    使用c++實現(xiàn)OpenCV繪制圓端矩形

    這篇文章主要介紹了使用c++實現(xiàn)OpenCV繪制圓端矩形,其中著重的講解了OpenCV使用過程中需要注意的一些小細節(jié),避免浪費大家在開發(fā)過程中浪費多余的時間
    2021-08-08
  • Qt 實現(xiàn)桌面雪花飄落代碼

    Qt 實現(xiàn)桌面雪花飄落代碼

    這篇文章主要介紹了Qt實現(xiàn)桌面雪花飄落代碼,有需要的朋友可以參考一下
    2013-12-12
  • C++中Overload,Override,Hide之間的區(qū)別

    C++中Overload,Override,Hide之間的區(qū)別

    重載overload,這個概念是大家熟知的。在同一可訪問區(qū)內(nèi)被聲名的幾個具有不同參數(shù)列的(參數(shù)的類型、個數(shù)、順序不同)同名函數(shù),程序會根據(jù)不同的參數(shù)列來確定具體調(diào)用哪個函數(shù),這種機制就是重載
    2013-09-09
  • 詳解C++中菱形繼承的原理與解決方法

    詳解C++中菱形繼承的原理與解決方法

    C++中的菱形繼承是多繼承的一種特殊情況,本文將通過海里帶大家了解一下菱形繼承形成的原因以及想應的解決方法,感興趣的可以了解一下
    2023-02-02
  • opencv檢測直線方法之形態(tài)學方法

    opencv檢測直線方法之形態(tài)學方法

    這篇文章主要為大家詳細介紹了opencv檢測直線方法之形態(tài)學方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12

最新評論