20. 有效的括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
思路: 使用栈解决
class Solution {
public:
bool isValid(string s) {
stack<char> mystack;
map<char, char> mymap;
mymap[']'] = '[';
mymap[')'] = '(';
mymap['}'] = '{';
for (int i = 0; i < s.length(); i++) {
if (s[i] == '(' || s[i] == '{' || s[i] == '[') mystack.push(s[i]);
else {
if (mystack.empty()) return false;
if (mymap[s[i]] == mystack.top()) {
mystack.pop();
} else {
return false;
}
}
}
return mystack.empty();
}
};
//参考写法
class Solution {
public:
bool isValid(string s) {
if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求
stack<char> st;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') st.push(')');
else if (s[i] == '{') st.push('}');
else if (s[i] == '[') st.push(']');
// 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
// 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
else if (st.empty() || st.top() != s[i]) return false;
else st.pop(); // st.top() 与 s[i]相等,栈弹出元素
}
// 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
return st.empty();
}
};
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除
思路: 栈实现
class Solution {
public:
string removeDuplicates(string s) {
stack<char> mystack;
for (int i = 0; i < s.length(); i++) {
if (mystack.empty()) {
mystack.push(s[i]);
continue;
}
if (s[i] == mystack.top()) {
mystack.pop();
} else {
mystack.push(s[i]);
}
}
string result="";
while (!mystack.empty()) {
result += mystack.top();
mystack.pop();
}
reverse(result.begin(), result.end());
return result;
}
};
//优化写法
//时间复杂度: O(n)
//空间复杂度: O(n)
class Solution {
public:
string removeDuplicates(string S) {
stack<char> st;
for (char s : S) {
if (st.empty() || s != st.top()) {
st.push(s);
} else {
st.pop(); // s 与 st.top()相等的情况
}
}
string result = "";
while (!st.empty()) { // 将栈中元素放到result字符串汇总
result += st.top();
st.pop();
}
reverse (result.begin(), result.end()); // 此时字符串需要反转一下
return result;
}
};
150. 逆波兰表达式求值
给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式
补充知识:
- string的使用
//string的构造函数
string str1;
string str2("str2");
string str3(str2);
string str4(str3,1,2);//从索引1开始,取两个字符, "tr"
//索引
cout << str2[2] << endl;//按照正常数组索引
//获取长度
size_t len = str2.length();
//修改字符串
str2.clear();
str2.push_back('c');
str2.pop_back();
str2.insert(0, "inserted"); //在索引0的位置, 插入, 结果为 inserted
str2.erase(0, 2); //在索引0的位置, 删除2个, 结果为 serted
str2.replace(0, 2, "123"); //在索引0的地方,前2个字符删除, 结果为 123rted
str2.replace(str2.begin(), str2.end(), "replaced");//以迭代器的范围, 结果为 replaced
//拼接(往后添加)
str1 += str2;
str1.append("append");
//字符串比较
str1 = "str1";
str2 = "str2";
if (str1 < str2) {
cout << "true" << endl;//按照字典的顺序排列
//"str1" < "str2", 比较的是两个字符串字面量的值,实际上比较的是它们在内存中的地址,而不是它们的值
//str1 < str2, 实际上是按照字典顺序来比较它们的ASCII码值, 返回结果为 true
}
//整数、浮点数到字符串的转换
str1 = to_string(int(123));
str2 = to_string(double(3.14));
//字符串至整数,浮点数
int num1 = std::stoi("123");
long num2 = std::stol("123");
long long num3 = std::stoll("123");
float num4 = std::stof("123.123");
double num5 = std::stod("123.123");
long double num6 = std::stold("123.123");
- stringstream的使用
//两种构造方式会导致新增元素的方式不同
stringstream ss1; //构造方式1(会从最后追加数据)
ss1 << "fre"; //结果: fre
ss1 << "gre"; //结果: fregre
stringstream ss2("asd"); //构造方式2(会从索引0开始追加数据)
ss2 << "r"; //结果: rsd
ss2 << "13"; //结果: r13
ss2 << "hy"; //结果: r13hy
//修改或清空
ss1.str("");//修改ss1.str("123");
ss1.clear();//只是清空标志位的状态, 不会对内容进行变动
//输出
cout << "ss1: " << ss1.str() << endl;
//int 类型转换为 string 类型
ss1 << (int)1000;
string str;
ss1 >> str; // str = "1000"
//string类型转换为 int 类型
ss1.str("10");
ss1.clear();
int num1 = 0;
ss1 >> num1;
cout << "num1: " << num1 << endl;
//分隔字符串
ss1.str("ab cd ef");
ss1.clear();
while (ss1 >> str){
cout << str << endl;
}
//以'_'分隔
ss1.str("ab_cd_ef");
ss1.clear();
while (getline(ss1, str, '_'))
cout << str << ' ';
- switch函数
- 在C++中,switch 语句只能用于整型(如 int、char、bool、enum 等), 不能使用 string
自行实现
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> mystack;
for (auto it = tokens.begin(); it != tokens.end(); it++) {
if (*it != "+" && *it != "-" && *it != "*" && *it != "/") {
stringstream ss;
int num = 0;
ss << * it;
ss >> num;
mystack.push(num);
continue;
}
int value1 = mystack.top();
mystack.pop();
int value2 = mystack.top();
mystack.pop();
switch((*it)[0]) {
case '+' :
mystack.push(value2 + value1);
break;
case '-' :
mystack.push(value2 - value1);
break;
case '*' :
mystack.push(value2 * value1);
break;
case '/' :
mystack.push(value2 / value1);
break;
default :
}
}
return mystack.top();
}
};