301删除无效的括号(广度优先搜索,BFS——困难)

1、题目描述

删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。

说明: 输入可能包含了除 ( 和 ) 以外的字符。

2、示例 

输入: "()())()"
输出: ["()()()", "(())()"]

3、题解

为何用BFS而不是DFS?
利用BFS理解起来要远远比DFS要简单的多,因为这道题说的是删除最少的括号!!,如果我们每次只删除一个括号,然后观察被删除一个括号后是否合法,如果已经合法了,我们就不用继续删除了。因此我们并不需要将遍历进行到底,而是层层深入,一旦达到需求,就不再深入了。

基本思想:广度优先搜索BFS,BFS对当前层的所有string遍历,对每个string中删除一个括号当做下一层的string,遍历当前层的所有string的时候,判断string是否满足条件,如果满足置flag=true且加入res,结束。

优化点:

  • 第一对于当前层的string删除一个括号当做下一层的string这个过程可能产生重复的string所以利用set去重,时间复杂度O(logn)一开始使用vector时间复杂度O(n)超时
  • 第二对于去除某个括号不要使用erase函数时间复杂度较高,使用substr拼接更快
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
class Solution {
public:
	vector<string> removeInvalidParentheses(string s) {
		//基本思想:广度优先搜索BFS,BFS对当前层的所有string遍历,对每个string中删除一个括号当做下一层的string
		//遍历当前层的所有string的时候,判断string是否满足条件,如果满足置flag=true且加入res,结束
		//优化点:第一对于当前层的string删除一个括号当做下一层的string这个过程可能产生重复的string所以利用set去重,时间复杂度O(logn)一开始使用vector时间复杂度O(n)超时
		//第二对于去除某个括号不要使用erase函数时间复杂度较高,使用substr拼接更快
		vector<string> res;
		queue<string> queues;
		bool flag = false;
		queues.push(s);
		while (!queues.empty())
		{
			if (flag)  break;
			int len = queues.size();
			set<string> level;
			while (len--)
			{
				string cur = queues.front();
				if (checkParentheses(cur))
				{
					flag = true;
					res.push_back(cur);
				}	
				for (int i = 0; i < cur.size(); i++)
				{
					if (cur[i] == '(' || cur[i] == ')')
					{
						string temp = cur.substr(0,i)+cur.substr(i+1, cur.size()-i-1);
						if (level.find(temp) == level.end())
						{
							level.insert(temp);
							queues.push(temp);
						}
					}	
				}
				queues.pop();
			}
		}
		return res;
	}
	bool checkParentheses(string s)
	{
		vector<char> st;
		for (int i = 0; i < s.size(); i++)
		{
			if (s[i] == '(')
				st.push_back('(');
			else if (s[i] == ')')
			{
				if (st.empty())
					return false;
				st.pop_back();
			}
		}
		return st.empty();
	}
};
int main()
{
	Solution solute;
	string s = ")()()i)())b(())h))))";
	vector<string> res = solute.removeInvalidParentheses(s);
	for_each(res.begin(), res.end(), [](const string& v) {cout << v << endl; });
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值