寻找合法字符串(招商银行信用卡中心2018秋招笔试)

给出一个正整数n,请给出所有的包含n个'('和n个')'的字符串,使得'('和')'可以完全匹配。

例如:

'(())()','()()()' 都是合法的;

'())()('是不合法的。

请按照__字典序__给出所有合法的字符串。

输入描述:

输入为1个正整数

输出描述:

输出为所有合法的字符串,用英文逗号隔开

示例1

输入

2

输出

(()),()()

思路:

可以采用暴力解法和深度优先遍历。

1.暴力法 :根据输入的n得到字符串的全排列(使用了std::next_permutation),然后排除不合法的,筛选出合法的字符串。具体筛选的方法可以借助栈,思路是遍历字符串,当遇到‘(’就入栈,当遇到‘)’就是出栈,判断是不是‘(’,如果是,则下一个,否则返回空串“”。特殊的,如果字符串第一个字符就遇到‘)’,此时栈还是空的,那么就直接返回空串“”。当循环结束,说明并没有返回空串“”,则说明该串合法,则返回当前的串。

2.深度优先遍历DFS:字符串总长度为2*n,当"("的个数小于n,则添加一个"(",并且总数加1;添加")"的规则苛刻一点,当")"的数目小于n,并且")"的数目小于"("时,才能添加")",这样才能保证有左括号可以匹配。

代码:

1.暴力解:

#include <iostream>

#include <algorithm>

#include <string>

#include <stack>

using namespace std;

string validStr(string ss){  //核心是遇到‘)’,看看之前有没有配对的‘(’.用到后进先出,所以考虑到 
                             //用栈
	stack<char> sc;
	
	for (int i = 0; i < ss.size(); i++){

		if (ss[i] == ')')
		{
			if (!sc.empty()){

				char c = sc.top();

				sc.pop();

				if (c != '(')

					return "";
			}
			else

				return "";
		}
		else {

			sc.push(ss[i]);
		
		}
	
	}

	return ss;
	

}

int main(){

	int n;

	cin >> n;

	string str = "";

	for (int i = 0; i <n;i++)
	{
		str += "(";
	}
	for (int i = 0; i < n; i++)
	{
		str += ")";
	}
	string scopy(str);  //这个合理字符串先输出,后续不输出。

	cout << str ;   //结果输出中第一个 ,后续输出都要加“,”+str的格式

	string res ="";
	do 
	{
		res=validStr(str);

		if (res != "" && res!=scopy) cout <<","<< res ;

	} while (next_permutation(str.begin(),str.end()));

	return 0;
}

2.深度优先遍历DFS

#include <iostream>

#include <algorithm>

#include <string>

#include <stack>

#include<vector>

using namespace std;

void DFS(int n,int x, int l, int r, string str, vector<string> &ret){

	if (x == 2 * n){

		ret.push_back(str);

		return;
	}

	if (l < n)  DFS(n,x + 1, l + 1, r,str+"(", ret);

	if (r<n && l>r) DFS(n,x+1,l,r+1,str+")",ret);

	return;
}



int main(){
      
	vector<string> ret;

	int n;

	cin >> n;

	DFS(n,0, 0, 0, "", ret);

	cout << ret[0];

	for (int i = 1; i < ret.size();i++)
	{
		cout << "," << ret[i];
	}

	 
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值