20. Valid Parentheses
仅供自己学习
思路:
因为括号匹配是有滞后性,且s后面的括号先完成配对,所以可以考虑用栈存储前面的括号,同时也保证匹配的顺序正确。
如果s的长度 不是2的倍数,那么肯定是无法配对的,这里判断是不是2的倍数我们使用 s.length() &1来判断,同时如果s的第一个元素为‘)’,‘]’,'}'则也是无法配对的,这些情况都直接返回 false
我们遍历s的每一个字符,如果栈未空的,且新的s得元素是 反向括号,那么我们就判断 该反向括号是否与栈顶的括号能配对,如果能配对就删除栈顶元素,并进入下一次循环。如果栈为空,或者栈不空但不满足配对条件,就把新元素加入进来,再进行下一次循环。如果栈不空且配对不了,就直接返回false再进行下一次循环。
如果能全部正确配对,那么栈最后就会空,返回 stack.empty()即可。
代码:
1 class Solution { 2 public: 3 bool isValid(string s) { 4 stack<char> st; 5 if(s.length()&1||s[0]==')'||s[0]==']'||s[0]=='}') return false; 6 for(int i=0;i<s.length();++i){ 7 char c=s[i]; 8 if(!st.empty()){ 9 if((c==')'&&st.top()=='(')||(c==']'&&st.top()=='[')||(c=='}'&&st.top()=='{')){ 10 st.pop(); 11 continue; 12 } 13 else if(c==')'||c==']'||c=='}') return false; 14 15 } 16 st.push(c); 17 } 18 19 return st.empty(); 20 } 21 };
但是 如果删除第13条,运行速度会极大提高,额外判断时间比全部加进来靠判断栈是否为空更花费时间
代码:
class Solution { public: bool isValid(string s) { stack<char> st; if(s.length()&1||s[0]==')'||s[0]==']'||s[0]=='}') return false; for(int i=0;i<s.length();++i){ char c=s[i]; if(!st.empty()){ if((c==')'&&st.top()=='(')||(c==']'&&st.top()=='[')||(c=='}'&&st.top()=='{')){ st.pop(); continue; } } st.push(c); } return st.empty(); } };
还有一种方法就是用unordered_map<char,char> pairs进行存储,如果新的s的元素在pairs中为key值,且栈顶元素与该key值得value值相同,那么就是能配对的。这里我们对pairs如此存储
unordered_map<char,char> pairs={
{')','('},
{']','['},
{'}','{'},
};
闭括号作为key值,当遍历到s的闭括号后我们才会进行配对,如果配对成功就删除栈顶元素。如果没有到闭括号,我们就持续将开括号加入进栈里。
代码:
1 class Solution { 2 public: 3 bool isValid(string s) { 4 stack<char> st; 5 if(s.length()&1||s[0]==')'||s[0]==']'||s[0]=='}') return false; 6 unordered_map<char,char> pairs={ 7 {')','('}, 8 {']','['}, 9 {'}','{'}, 10 }; 11 for(char c:s){ 12 if(pairs.count(c)){ //对c是不是闭括号进行判断,是的话就进入配对环节 13 if(st.empty()||st.top()!=pairs[c]) 14 return false; 15 st.pop(); 16 } 17 else{ //不是闭括号就将开括号加入进栈里。 18 st.push(c); 19 } 20 21 } 22 23 return st.empty(); 24 } 25 };