Thursday, July 4, 2013

Longest valid parenthesis@leetcode

刷题必备书籍Cracking the Coding Interview: 150 Programming Questions and Solutions 

简历:The Google Resume: How to Prepare for a Career and Land a Job at Apple, Microsoft, Google, or any Top Tech Company
算法学习书籍:Introduction to Algorithms
编程珠玑:Programming Pearls (2nd Edition)
C++ 学习:The C++ Programming Language, 4th Edition
经典操作系统书籍,龙书:Operating System Concepts
创业:The Start-up of You: Adapt to the Future, Invest in Yourself, and Transform Your Career
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.
» Solve this problem

这道题我卡了很久,也没有想好完全的解法,第一想到的就是用stack,但是那样做出来的是整个string里面所有okay的parenthesis的和。网上看了几个巧妙的办法,用一个数组倒着来记录最大的valid parenthesis数。

这道题可以用一维动态规划逆向求解。假设输入括号表达式为String s,维护一个长度为s.length的一维数组dp[],数组元素初始化为0。 dp[i]表示从s[i]到s[s.length - 1]最长的有效匹配括号子串长度。则存在如下关系:
  • dp[s.length - 1] = 0;
  • 从i - 2 -> 0逆向求dp[],并记录其最大值。若s[i] == '(',则在s中从i开始到s.length - 1计算s[i]的值。这个计算分为两步,通过dp[i + 1]进行的(注意dp[i + 1]已经在上一步求解):
    • 在s中寻找从i + 1开始的有效括号匹配子串长度,即dp[i + 1],跳过这段有效的括号子串,查看下一个字符,其下标为j = i + 1 + dp[i + 1]。若j没有越界,并且s[j] == ‘)’,则s[i ... j]为有效括号匹配,dp[i] =dp[i + 1] + 2。
    • 在求得了s[i ... j]的有效匹配长度之后,若j + 1没有越界,则dp[i]的值还要加上从j + 1开始的最长有效匹配,即dp[j + 1]。

1 comment:

  1. 其实第一个DP算法,我觉得DP[i]的意思,并不是表示从s[i]到s[s.length - 1]最长的有效匹配括号子串长度。比如说该算法中,所有)位置的DP都是0. 还有比如“(((()”,求出来的DP数组是[0,0,0,2,0],它的意思我觉得是,包含当前位置的最大有效匹配长度。

    ReplyDelete

Leetcode 316. Remove Duplicate Letters

 这道题表面问的是如何删除重复,实际在问如何从多个字符选取一个保留,从而让整个字符串按升序排列。那么策略就是对于高顺位的字符比如‘a',就要选靠前位置的保留,而低顺位字符如’z'则应该尽量选取靠后位置保留。 算法大概思路:每看到一个字符,我们要决定是否保留 1. ...