1. 程式人生 > >leetcode 32. Longest Valid Parentheses 最長有效括號長度

leetcode 32. Longest Valid Parentheses 最長有效括號長度

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

For “(()”, the longest valid parentheses substring is “()”, which has length = 2.

Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.

這個題的意思就是尋找最長的括號配對的長度,並返回length。基本的想法就是用棧來實現。從字串的第一個位置開始讀起,遇到左括號的話就入棧,遇到右括號的話就將棧頂元素彈出,並且判斷當前序列的最長長度。棧裡儲存的是左括號的位置。
具體遇到右括號時,有如下幾種情況需要考慮:

  1. 當前棧內無元素,則用start變數記錄當前右括號的位置,表明下次比較從該右括號下一個位置開始判斷;

  2. 當前棧內有元素,則將棧頂元素彈出。如果彈出後的棧為空,則表明當前括號匹配,這時計算出當前的最長序列長度,即當前位置的值減去start的值即是;

  3. 當前棧內又元素且彈出後的棧內仍然有元素,則最長序列長度為當前元素位置減去棧頂元素的位置。

程式碼如下:

import java.util.Stack;

public class Solution 
{
    /*
     * 這道題的思想就是使用棧遍歷一次思想對打有效括號的匹配。
     * 從字串的第一個位置開始讀起,遇到左括號的話就入棧,遇到右括號的話就將棧頂元素彈出,並且判斷當前序列的最長長度。
     * 棧裡儲存的是左括號的位置。
     * 
     * 具體遇到右括號時,有如下幾種情況需要考慮:
     * 1. 當前棧內無元素,則用start變數記錄當前右括號的位置,
     * 表明下次比較從該右括號下一個位置開始判斷;
     * 
     * 2. 當前棧內有元素,則將棧頂元素彈出。如果彈出後的棧為空,
     * 則表明當前括號匹配,這時計算出當前的最長序列長度,即當前位置的值減去start的值即是;
     * 
     * 3. 當前棧內又元素且彈出後的棧內仍然有元素,
     * 則最長序列長度為當前元素位置減去棧頂元素的位置。
     * 
     * 本演算法僅需要掃描一遍字串,所以時間複雜度為O(n);
     * 
     * */
public int longestValidParentheses(String s) { if(s==null || s.length()<=0) return 0; int beginIndex=0,maxLen=0; Stack<Integer> stack=new Stack<>(); for(int i=0;i<s.length();i++) { //遇到 ( 均壓入棧,壓入的是index if(s.charAt(i)=='(') stack.push(i); else // ')' { //遇到空,說明當前無法構成合理的括號配對 if(stack.isEmpty()) beginIndex=i+1; else { stack.pop(); if(stack.isEmpty()) maxLen=Math.max(maxLen, i-beginIndex+1); else maxLen=Math.max(maxLen, i-(stack.peek()+1)+1); } } } return maxLen; } }

下面是C++的做法,

程式碼如下:

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;

class Solution 
{
public:
    int longestValidParentheses(string s) 
    {
        if (s.length() <= 1)
            return 0;

        int beginIndex = 0, maxLen = 0;
        stack<int> stk;
        for (int i = 0; i < s.length(); i++)
        {
            if (s[i] == '(')
                stk.push(i);
            else
            {
                if (stk.empty())
                    beginIndex = i + 1;
                else
                {
                    stk.pop();
                    if (stk.empty())
                        maxLen = max(maxLen, i - beginIndex + 1);
                    else
                        maxLen = max(maxLen, i - (stk.top() + 1) + 1);
                }
            }
        }
        return maxLen;
    }
};