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. // Longest Valid Parenthese
  2. // 使用栈,时间复杂度O(n),空间复杂度O(n)
  3. public class Solution {
  4. public int longestValidParentheses(String s) {
  5. // the position of the last ')'
  6. int maxLen = 0, last = -1;
  7. // keep track of the positions of non-matching '('s
  8. Stack<Integer> lefts = new Stack<>();
  9. for (int i = 0; i < s.length(); ++i) {
  10. if (s.charAt(i) =='(') {
  11. lefts.push(i);
  12. } else {
  13. if (lefts.empty()) {
  14. // no matching left
  15. last = i;
  16. } else {
  17. // find a matching pair
  18. lefts.pop();
  19. if (lefts.empty()) {
  20. maxLen = Math.max(maxLen, i-last);
  21. } else {
  22. maxLen = Math.max(maxLen, i-lefts.peek());
  23. }
  24. }
  25. }
  26. }
  27. return maxLen;
  28. }
  29. }

Dynamic Programming, One Pass

  1. // Longest Valid Parenthese
  2. // 两遍扫描,时间复杂度O(n),空间复杂度O(1)
  3. // @author 曹鹏(http://weibo.com/cpcs)
  4. class Solution {
  5. public int longestValidParentheses(final String s) {
  6. int result = 0, depth = 0, start = -1;
  7. for (int i = 0; i < s.length(); ++i) {
  8. if (s.charAt(i) == '(') {
  9. ++depth;
  10. } else {
  11. --depth;
  12. if (depth < 0) {
  13. start = i;
  14. depth = 0;
  15. } else if (depth == 0) {
  16. result = Math.max(result, i - start);
  17. }
  18. }
  19. }
  20. depth = 0;
  21. start = s.length();
  22. for (int i = s.length() - 1; i >= 0; --i) {
  23. if (s.charAt(i) == ')') {
  24. ++depth;
  25. } else {
  26. --depth;
  27. if (depth < 0) {
  28. start = i;
  29. depth = 0;
  30. } else if (depth == 0) {
  31. result = Math.max(result, start - i);
  32. }
  33. }
  34. }
  35. return result;
  36. }
  37. }

两遍扫描

  1. // Longest Valid Parenthese
  2. // 两遍扫描,时间复杂度O(n),空间复杂度O(1)
  3. // @author 曹鹏(http://weibo.com/cpcs)
  4. class Solution {
  5. public int longestValidParentheses(final String s) {
  6. int result = 0, depth = 0, start = -1;
  7. for (int i = 0; i < s.length(); ++i) {
  8. if (s.charAt(i) == '(') {
  9. ++depth;
  10. } else {
  11. --depth;
  12. if (depth < 0) {
  13. start = i;
  14. depth = 0;
  15. } else if (depth == 0) {
  16. result = Math.max(result, i - start);
  17. }
  18. }
  19. }
  20. depth = 0;
  21. start = s.length();
  22. for (int i = s.length() - 1; i >= 0; --i) {
  23. if (s.charAt(i) == ')') {
  24. ++depth;
  25. } else {
  26. --depth;
  27. if (depth < 0) {
  28. start = i;
  29. depth = 0;
  30. } else if (depth == 0) {
  31. result = Math.max(result, start - i);
  32. }
  33. }
  34. }
  35. return result;
  36. }
  37. }

相关题目

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/java/stack-and-queue/stack/longest-valid-parentheses.html