zoukankan      html  css  js  c++  java
  • LeetCode: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.


    算法1

    这道题首先想到的是动态规划, 字符串为s,设bool数组dp[i][j]表示子串s[i…j]是否可以完全匹配,那么动态规划方程如下:

    • 初始化dp数组为false
    • 如果dp[i+1][j-1] == true && s[i] == ‘(’&&s[j] == ‘)’或者 存在k = i+1…j-1 使得dp[i][k] == true && dp[k+1][j] = true ,则dp[i][j] = true

    方程的意思是:要使子串s[i…j]能够完全匹配,那么有以下两种情况可以满足:a、子串s[i+1…j-1]完全匹配,且s[i]、s[j]是左右两个半括号;b、存在某个k,使得两个子串s[i…k]、s[k+1…j]都能完全匹配.

    求得所有dp[i][j]后,最长匹配子串的长度 = max {j-i}, 其中 dp[i][j] = true;

    下面代码中isValid相当于方程中的dp,注意到子串长度为奇数时,子串可能完全匹配。概算大时间复杂度为O(n^3),oj上大数据超时

    class Solution {
    public:
        int longestValidParentheses(string s) {
            const int len = s.size();
            bool isValid[len][len];
            memset(isValid, 0, sizeof(isValid));
            int res = 0;
            for(int i = 0; i < len-1; i++)
                if(s[i] == '(' && s[i+1] == ')')
                {
                    isValid[i][i+1] = true;
                    res = 2;
                }
            for(int k = 4; k <= len; k+=2)//k表示子串长度,只有长度为偶数的子串才可能是合法括号
                for(int i = 0; i <= len-k; i++)//i表示子串的起始位置
                {
                    if(isValid[i+1][i+k-2] && s[i] == '(' && s[i+k-1] == ')')
                        isValid[i][i+k-1] = true;
                    else
                    {
                        for(int j = i+1; j <= i+k-3; j++)
                            if(isValid[i][j] && isValid[j+1][i+k-1])
                                isValid[i][i+k-1] = true;
                    }
                    if(isValid[i][i+k-1])res = k;
                }
            return res;
        }
    };

    算法2

    在处理括号匹配问题上,我们一般使用栈来解决。这一题也可以。

    顺序扫描字符串:

    初始化:在栈中压入-1

    一、若碰到‘(’,则把当前位置压入栈中

    二、若碰到‘)’:

         (1)、如果栈顶元素不是‘(’,则把当前位置压入栈中;

         (2)、如果栈顶元素时‘(’:栈顶元素出栈,当前的合法子串长度 = 当前字符索引 - 新的栈顶元素;更新最大子串长度

    例如以下字符串

    image

    扫描到第0个字符‘(’时,0入栈

    扫描到第1个字符‘)’时,栈顶对应字符为‘(’,把栈顶0出栈,当前合法子串长度 = 1 - 新的栈顶元素(-1) = 2;

    扫描到第2个字符‘)’时,栈顶为-1,因此2入栈

    扫描到第3个字符‘(’时,3入栈

    扫描到第4个字符‘)’时,栈顶对应字符为‘(’,把栈顶3出栈,当前合法子串长度 = 4 - 新的栈顶元素(2) = 2;                                 本文地址

    扫描到第5个字符‘(’时,5入栈

    扫描到第6个字符‘)’时,栈顶对应字符为‘(’,把栈顶5出栈,当前合法子串长度 = 6 - 新的栈顶元素(2) = 4;

    需要注意的是:当前合法子串当长度 != 当前索引 - 与当前的‘)’匹配的‘(’的索引 + 1, 例如扫描到第6个字符‘)’时,当前合法子串长度不是等于6-5+1 = 2,还要考虑到它前面已经匹配的3、4号位

    算法时间空间复杂度都是O(n)

    class Solution {
    public:
        int longestValidParentheses(string s) {
            const int len = s.size();
            stack<int> sta;
            int res = 0;
            sta.push(-1);//为了处理边界条件,在栈底添加-1
            for(int i = 0; i < len; i++)
            {
                if(s[i] == '(')
                    sta.push(i);
                else
                {
                    int topIndex = sta.top();
                    if(topIndex >= 0 && s[topIndex] == '(')//s[i]可以和s[a]匹配
                    {
                        sta.pop();
                        if(res < i - sta.top())res = i - sta.top();
                    }
                    else sta.push(i);
                }
            }
            return res;
        }
    };

    【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3771122.html

  • 相关阅读:
    Python学习札记(十五) 高级特性1 切片
    LeetCode Longest Substring Without Repeating Characters
    Python学习札记(十四) Function4 递归函数 & Hanoi Tower
    single number和变体
    tusen 刷题
    实验室网站
    leetcode 76. Minimum Window Substring
    leetcode 4. Median of Two Sorted Arrays
    leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions 、434. Number of Islands II(lintcode) 并查集 、178. Graph Valid Tree(lintcode)
    刷题注意事项
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3771122.html
Copyright © 2011-2022 走看看