题意:
给定一个包含三种字符(左括号,右括号和问号)的字符串,其中 问号 可以改为 左括号 或 右括号。
现问是否可以将原字符串修改为 合法的(只包含左括号 或 右括号)的字符串。
如果能,返回修改后的字符串;否则返回“Impossible”。
方法一:
贪心
思路:首先,如果字符串长度是奇数,则返回“Impossible”;计算字符串中的左括号数 num,再用字符串长度的一半减去左括号数,得到剩余的左括号数。如果剩余的左括号数小于零,则返回“Impossible”;
接着用剩余的左括号数去先填充等量的(问号的字符),而最后的一些问号字符才用右括号填充。
最后,判断修改后的字符串是否合法。
class Solution { public: string MissingBrackets(string brackets) { int n=brackets.size(); if(n%2==1)//奇数长度,则失败 return "Impossible"; int num=0;//左括号数量 for(int i=0;i<n;i++){ if(brackets[i]=='(') num++; } num=n/2-num;//剩余左括号数量 if(num<0) return "Impossible"; for(int i=0;i<n;i++){ if(brackets[i]=='?'){ if(num){//填充左括号 brackets[i]='('; num--; }else{//填充右括号 brackets[i]=')'; } } } int flag=0;//判断字符串是否合法 for(int i=0;i<n;i++){ if(brackets[i]=='(') flag++; else flag--; if(flag<0)//如果是负数,则不合法 return "Impossible"; } return brackets; } };
时间复杂度:空间复杂度:
方法二:
用栈判断是否合法
思路:与方法一思路相同,提供另一种判断字符串是否合法的方法。对于贪心得到的最后值包含左右括号的字符串,利用栈实现判断。
如果遇到左括号,则入栈;
如果遇到左括号,则判断栈是否为空:如果栈空,则返回"Impossible";否则,令栈顶元素(左括号)出栈。
最后再判断栈是否为空:如果栈不空,则返回"Impossible"。
class Solution { public: string MissingBrackets(string brackets) { int n=brackets.size(); if(n%2==1)//奇数长度,则失败 return "Impossible"; int num=0;//左括号数量 for(int i=0;i<n;i++){ if(brackets[i]=='(') num++; } num=n/2-num;//剩余左括号数量 if(num<0) return "Impossible"; for(int i=0;i<n;i++){ if(brackets[i]=='?'){ if(num){//填充左括号 brackets[i]='('; num--; }else{//填充右括号 brackets[i]=')'; } } } stack<char> st; for(int i=0;i<n;i++){ if(brackets[i]=='(')//左括号入栈 st.push('('); else if(!st.empty())//遇到右括号且z st.pop(); else return "Impossible"; } if(!st.empty())//如果栈不空,则不合法 return "Impossible"; return brackets; } };
时间复杂度:空间复杂度: