Day 1.11
有效的括号
题目
思路(1)
class Solution {
public:
bool isValid(string s) {
int a = s.size();
int b = 0;
if(a % 2 == 1)return false;
else if(a == 0)return true;
else{
for(int i = 0; i < a-1 ; ++i){
int j = i + 1;
while(j < a){
if(s[i] + 1 == s[j] || s[i] + 2 == s[j]){
b++;
s[j]=0;
break;
}
else j += 2;
}
}
}
if(b == a/2)
return true;
return false;
}
};
在此基础上改进后
class Solution {
public:
bool isValid(string s) {
int a = s.size();
int b = 0,m = 0,k = 0;
if(a % 2 == 1)return false;
else if(a == 0)return true;
else{
for(int i = 0; i < a-1 ; ++i){
int j = i + 1;
if(s[i] == 0)continue;
if(m==0){
while(j < a){
if(s[i] + 1 == s[j] || s[i] + 2 == s[j]){
b++;
s[j]=0;
break;
}
else j += 2;
m = j;
}
}
else{
while(j < a){
if(s[i] + 1 == s[j] || s[i] + 2 == s[j]){
b++;
s[j]=0;
break;
}
else j += 2;
k++;
}
if(j>m)return false;
if(k==0)m = 0;
else {m = j;k = 0;}
}
}
}
if(b == a/2)
return true;
return false;
}
};
确认是错误思路,放弃
思路(2)
#include<iostream>
using namespace std;
int main()
{
char s[100];
cin>>s;
int a = 0,i = 0,k = -1;
for(int j = 0;s[j]!='\0';++j){
if(s[j]==40||s[j]==41||s[j]==91||s[j]==93||s[j]==123||s[j]==125){
a++;
}
}
if(a % 2 == 1){cout<<" false";return 0;}
else if(a == 0){cout<<" true";return 0;}
else{
while(i < a){
while(s[k]==0)k--;
if(s[i]==40||s[i]==91||s[i]==123){
k=i;
}
if(s[i]==41||s[i]==93||s[i]==125){
if((s[k]==s[i]-1)||(s[k]==s[i]-2)){
s[k] = s[i] = 0;
}
else{
cout<<"false";
return 0;
}
}
i++;
}
while(s[k]==0)k--;
if(k!=-1){cout<<"false";return 0;}
cout<<"true";
return 0;
}
}
在VS2010 中测试多组数据正确(包括“()”)但在力扣中显示错误
class Solution {
public:
bool isValid(string s) {
int a = 0,i = 0,k = -1;
for(int j = 0;s[j]!='\0';++j){
if(s[j]==40||s[j]==41||s[j]==91||s[j]==93||s[j]==123||s[j]==125){
a++;
}
}
if(a % 2 == 1){return false;}
else if(a == 0){return true;}
else{
while(i < a){
while(s[k]==0)k--;
if(s[i]==40||s[i]==91||s[i]==123){
k=i;
}
if(s[i]==41||s[i]==93||s[i]==125){
if((s[k]==s[i]-1)||(s[k]==s[i]-2)){
s[k] = 0;s[i] = 0;
}
else{
return false;
}
}
i++;
}
while(s[k]==0)k--;
if(k!=-1){return false;}
else{return true;}
}
}
};
思路(3)(答案)
代码
class Solution {
public:
bool isValid(string s) {
unordered_map<char,int> m{{'(',1},{'[',2},{'{',3},
{')',4},{']',5},{'}',6}};
stack<char> st;
bool istrue=true;
for(char c:s){
int flag=m[c];
if(flag>=1&&flag<=3) st.push(c);
else if(!st.empty()&&m[st.top()]==flag-3) st.pop();
else {istrue=false;break;}
}
if(!st.empty()) istrue=false;
return istrue;
}
};
结果
笔记
与思路二相似,但运用栈最简便
答案加上傻瓜式注解
class Solution {
public:
bool isValid(string s) {
/*
1. 首先设定哈希表,依次保存三个开括号`(分别对应1,2,3)`与三个闭括号`(分别对应4,5,6)`,以及栈`(只放入开括号,遇到对应闭括号,则出栈)`还有最后一个正确bool值,判断是否正确`(比如第一个就是闭括号,必然错误)`,且默认为真
2. for遍历string字符串
1. 如果为开括号,入栈
2. 否则栈非空时,且接下来的为对应闭括号,则出栈
3. 否则(此时隐含表达为'这是个闭括号'),则bool值为假
3. 如果栈非空时,则说明闭括号少了,bool为假
4. 返回bool值
*/
//哈希表,存储,以及栈
unordered_map<char,int> m{{'(',1},{'[',2},{'{',3},{')',4},{']',5},{'}',6}};
stack <char> st;
//用来判断如果第一个字符就是闭括号怎么办
bool isTrue =true;
//遍历string s
for(char c:s)
{
//如果为开括号,将其入栈
if(1<=m[c]&&m[c]<=3)st.push(c);
//以下两行都是错的,而且两行语法就错了,意味着不能正确出栈了
//else if(!st.empty() && m.find(m[c]-3)!=m.end() )st.pop();
//else if(!st.empty() && st.top()==m[c]-3)st.pop();
//如果栈非空,且栈顶元素与接下来的字符(闭括号)相对应,出栈
else if(!st.empty() && m[st.top()]==m[c]-3 )st.pop();
//否则俩个条件都不满足,意味着一开始就是个闭括号,或者闭括号多了,没有对应开括号在栈里面
else
{
isTrue=false;
break;//这里别忘了啊
}
}
//如果for遍历完后,栈非空,意味着开括号多了,则非法
if(!st.empty()) isTrue=false;
//返回bool值即可
return isTrue;
}
};
补充栈的几个常用方法
Stack是Vector的一个子类,它实现标准的后进先出堆栈。
Stack 仅仅定义了创建空堆栈的默认构造函数。
Stack包括了由Vector定义的所有方法,同时增加了几种它自己定义的方法,介绍如下:
boolean empty( )-——-如果堆栈是空的,则返回true,当堆栈包含元素时,返回false。
Object peek( )———–返回位于栈顶的元素,但是并不在堆栈中删除它。
Object pop( )————返回位于栈顶的元素,并在进程中删除它。
Object push (Object element )———将element压入堆栈,同时也返回element。
int search(Object element)———在堆栈中搜索element,如果发现了,则返回它相对于栈顶
的偏移量。否则,返回-1。