题目描述
题目给出括号序列brackets,要求判断此序列是否合法。并且具体操作是将??改为'('或者')'。brackets只由'?','(',')'构成。
合法的括号序列的定义:
1.空字符为合法括号序列
2.(+合法括号序列+) 为合法括号序列
3.()+合法括号序列为合法括号序列
如果能构造出来则返回恢复后任意合法的括号序列,否则返回Impossible
方法一:暴力求解
求解思路
对于本题目的求解,我们可以用暴力遍历的方法,首先我们声明两个变量,index变量记录问号出现的下标,dp变量记录两个问号之间括号的差值,正数表示差相应右括号,负数表示差相应绝对值的左括号。然后我们字符串进行遍历,并且将index和dp进行赋值,然后第二次遍历字符串,对每个问号所在的位置进行判断,如果存在左括号数加上差值都小于右括号则返回impossible,同理右括号也一样进行判断。最后对问号进行替换如果左括号多,则记录数大于0,从右向左进行右括号替换,同理右括号多的情况也按上述操作。最终我们即可通过暴力解法得到本题的答案。
解题代码
class Solution {
public:
string MissingBrackets(string brackets) {
int n = brackets.length();
if(n % 2) // 不为偶数一定不合法
return "Impossible";
vector<int> index; // index记录问号出现的位置
vector<int> mydp; // 记录两个问号之间左右括号个数的差
int a = 0; //维护两个问号之间左右括号个数的差
for(int i = 0; i < n; i++)
{ //找到?的位置,即之间的括号差
if(brackets[i] == '?')
{
index.push_back(i); // 位置入数组
mydp.push_back(a);
a = 0;
}
else if(brackets[i] == ')') // 遇到左加,遇到右减
a--;
else
a++;
}
index.push_back(n);
mydp.push_back(a);
n = index.size();
a = 0;
int q = 0; // 记录问号出现次数
for(int i = 0; i < n; i++)
{
a += mydp[i]; // 相差求和
if(-a > q++) // 如果前面一直少,且少得还大于?出现的次数
return "Impossible";
}
if(-a > index.size() - 1) // 把所有问号变为左括号都不能使左括号数量大于右括号
return "Impossible";
if(a > 0)
{ //左括号较多
a++;
for(int i = n - 2; i >= 0; i--)
{
if(a > 0)
{
brackets[index[i]] = ')';
a--;
}
else
{
brackets[index[i]] = '(';
a++;
}
}
}
else
{ //右括号较多
a--;
for(int i = 0; i < n - 1; i++)
{
if(a < 0)
{
a++;
brackets[index[i]] = '(';
}
else
{
brackets[index[i]] = ')';
a--;
}
}
}
return brackets; // 返回结果
}
};复杂度分析
时间复杂度:一层循环,因此时间复杂度为
空间复杂度:使用辅助数组index[N],dp[N],因此空间复杂度为
方法二:贪心思想求解
求解思路
对于本题我们也可以使用贪心的思想进行求解,对于合法的括号序列,左括号和右括号是相匹配的,因此我们可以从括号数入手,每次贪心地将差的左括号或者右括号补齐,最后验证整个序列是否合法。
解题代码
class Solution {
public:
string MissingBrackets(string brackets) {
int n = brackets.length();
int mycount = 0; // 存储括号数量
for(int i = 0; i < n; i++) // 统计左括号数
if(brackets[i] == '(')
mycount++;
if(n % 2 || mycount * 2 > n) // 不为偶数一定不合法,左括号数大于一般肯定不合法
return "Impossible";
int rest = n / 2 - mycount; // 还需要补充多少左括号
for(int i = 0; i < n; i++)
{
if(brackets[i] == '?' && rest != 0)
{
brackets[i] = '('; // 贪心思想对括号数进行更新
rest--;
}
else if(brackets[i] == '?')
brackets[i] = ')';
}
int all = 0;
for(int i = 0; i < n; i++)
{ //检查修改后内容是否合法
if(brackets[i] == '(')
all++;
else if(brackets[i] == ')')
all--;
if(all < 0)
return "Impossible";
}
return brackets; // 返回结果
}
};复杂度分析
时间复杂度:一层循环,因此时间复杂度为
空间复杂度:没有使用额外的内存地址空间,因此空间复杂度为

京公网安备 11010502036488号