算法设计与分析 第十周 最长有效括号


1.题目描述

在这里插入图片描述


2.选题原因

选择了一道动态规划的题目。但是感觉解这道题的方法不太像是动态规划的思想…一道匹配括号的题目,也是绞尽脑汁。


3.题目分析及算法

3.1分析

最容易想到的方法必然是用stack来解这道题目。思路如下:

3.2传统算法

遇到(将他放入栈,遇到)则查看栈中是否有相匹配的括号(即栈是否为空)

  • 栈为空,则说明该子串停止了。
  • 栈不为空,则弹出一个括号,匹配到了一堆括号,字串长度 + 2

3.3问题

很容易遇到问题,比如说遇到字串()((),此时,正常的输出结果应该是2,但是我们的结果是4,运算的过程中,在第三个字符(时,计数应该停止,但是栈继续计数,最后栈还剩下了元素。
如何避免这样的结果,有两种选择,第一种就是对两个字段分界的地方做记号,在循环之后返回标记点运算;第二种是提前判断。很明显,第二种方法更靠谱。
我们考虑,什么时候会出现一个字符串中断的情况:
第一种情况:出现(
第二种情况:出现)
出现)的时候很容易判断,如果相匹配的括号,就肯定会终止,而如果还有括号就可能不会终止,如果只剩下栈里只剩下一个括号,就有可能会终止。
出现(的时候就不好判断了,因为这回涉及到栈里的括号到最后能否匹配完的问题。
在这里,我们引入一种方法,用一个标记来标志字符串的开始位置,假设为start
只有当出现字符串终止的时候才有可能会调整start的位置。
字符串结束的几个条件:

  • 1、没有左括号与右括号匹配。
  • 2、有左括号和右括号匹配,但仅剩最后一个左括号。此时就可以更新最大值。
  • 3、有左括号和右括号匹配,且还有很多左括号。此时有可能多余的左括号会导致连接断开。

3.4算法

  • 初始化start = 0,开始遍历字符串。
  • 遇到(,加入栈。
  • 遇到),开始判断:
    • 栈为空,说明字符串长度断开,start = index + 1
    • 栈不为空,弹出元素,再次判断:
      • 栈中还有元素,更新MAX = index - 栈顶元素坐标
      • 栈中没有元素,更新MAX = index - start + 1

4.运行结果

在这里插入图片描述


5.源代码

class Solution {
public:
    int longestValidParentheses(string s) {
        string::iterator iter;	//迭代器
        int result = 0;			//记录最长的有效字符串长度
        int start = 0;			//记录有效字符串的开始位置
        stack<int> st;			//保存当前剩下的左括号的位置
        int i = 0;
        for (iter = s.begin(), i = 0; iter != s.end(); iter++, i++) {
        	if (*iter == '(') {					//左括号则插入栈中
        		st.push(i);
        	} else {							//否则判断
        		if (!st.empty()) {					//不为空,说明还有有效字符串
        			st.pop();
        			if (!st.empty()) {
        				result = max(result, i - st.top());
        			} else {
        				result = max(result, i - start + 1);
        			}
        		} else {							//为空,说明字符串已经结束了
        			start = i + 1;
        		}
        	}
        }
        return result;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值