LeetCode20:有效的括号
思路:左右要严格对应。
(({{[[]]}}))、(){}[]、({}[]) 这是正确的情况
)(、{{]} …就是不对的情况
此处的思路用的是栈,用暴力也可以做。
因此,只要将遍历到左边对应的就把右边对应的入栈,同时由于栈的特性,他的栈顶元素一定是和最后一次出现的左边对应遍历到后面,就会出现右边的元素,如果遍历到右边的元素,就和栈顶元素比较,相同则出栈,不同则错误。
遍历数组,
- 遇到左括号就把对应的右括号加到栈里面。
- 遇到右括号,
- 那先看此时栈是不是空,如果是空直接false:因为,此时s字符串前面的所有括号已经对应完毕,此时s字符串中还有右括号,那肯定false。
- 如果不为空但是,栈顶元素和s[i] 不同直接false:因此此时不能保证严格对应了。
- 其他情况:就是栈顶和s[i]相等,那就pop栈顶的右括号。
class Solution {
public boolean isValid(String s) {
/* 由于必须是左右对称的,
因此,只要将遍历到左边对应的就把右边对应的入栈,
同时由于栈的特性,他的栈顶元素一定是和最后一次出现的左边对应
遍历到后面,就会出现右边的元素,如果遍历到右边的元素,就和栈顶元素比较,相同则出栈,不同则错误。
*/
Stack<Character> stack = new Stack<>();
char[] ch = s.toCharArray();
for(int i=0;i<ch.length;i++){
if(ch[i] == '('){
stack.push(')');
}
else if(ch[i] == '{'){
stack.push('}');
}
else if(ch[i] == '['){
stack.push(']');
}
else if(stack.isEmpty() || stack.peek() != ch[i]){ // 如果还在遍历s,切这个元素是右边,但是stack已经为空的话。说明多了一个右括号,( [ ] ) )。多了一个右括号。或者如果栈顶元素,与当前s的元素不相等也是错了 [ }
return false;
}else{// 现在只剩正确的情况了,栈顶元素和ch[i] 相同
stack.pop();
}
}
return stack.isEmpty();
}
}
class Solution {
public:
bool isValid(string s) {
stack<char> st;
if(s.size() % 2) return false;
for(int i;i<s.size();i++){
if(s[i] == '('){
st.push(')');
}
else if(s[i] == '['){
st.push(']');
}
else if(s[i] == '{'){
st.push('}');
}
else if(st.empty() || st.top() != s[i]){
return false;
}
else{
st.pop();
}
}
return st.empty();
}
};
LeetCode1047删除字符串中的所有相邻重复项
思路:栈,
- 如果当前字符与栈顶元素相同,就出栈;
- 如果栈为空,或者栈顶元素与当前s[i]不同,就入栈
注意点:字符串的操作。
class Solution {
public String removeDuplicates(String s) {
// 用stack是一样的都需要判断isempty
// 在为空或者peek不等于ch[i]时 可以添加元素。
Stack<Character> stack = new Stack<>();
char[] ch = s.toCharArray();
for(int i=0;i<ch.length;i++){
if(stack.isEmpty() || stack.peek() != ch[i]){
stack.push(ch[i]);
}
else{
stack.pop();
}
}
String str = "";
while(!stack.isEmpty()){
str = stack.pop() + str;
}
return str;
}
}
class Solution {
public:
string removeDuplicates(string s) {
stack<int> st;
for(int i=0;i<s.size();i++){
if(st.empty() || s[i] != st.top()){
st.push(s[i]);
}
else {
st.pop();
}
}
//注意字符串的拼接 反转
string ans = "";
while(!st.empty()){
ans += st.top();
st.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
}
LeetCode150:逆波兰表达式求值
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for(String s : tokens){
if(s.equals("+")){
/* == 是看对象的引用是否相同,即查看内存中的地址是否相同。
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
在上面的例子中,s1 和 s2 引用的是同一个字符串常量对象,因此使用 == 比较它们的结果为 true;而 s3 引用的是一个新的字符串对象,因此与 s1 使用 == 比较的结果为 false。
equals 比较里面的元素是否相同。
*/
stack.push(stack.pop() + stack.pop()); // 两次pop得到num2(第一个pop)和nums1(第二个pop)
}
else if(s.equals("-")){
stack.push(-stack.pop() + stack.pop()); // 在nums2 前面加-,得到num1 - nums2
}
else if(s.equals("*")){
stack.push(stack.pop() * stack.pop());
}
else if(s.equals("/")){
int nums2 = stack.pop();
int nums1 = stack.pop();
stack.push(nums1/nums2);
}
else{
stack.push(Integer.valueOf(s));
}
}
return stack.peek();
}
}
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> s;
int size = tokens.size();
for(int i=0;i<size;i++){
if(tokens[i] == "+"){
int temp = s.top();
s.pop();
temp = s.top() + temp;
s.pop();
s.push(temp);
}
else if(tokens[i] == "-"){
int temp = s.top();
s.pop();
temp = s.top() - temp;
s.pop();
s.push(temp);
}
else if(tokens[i] == "*"){
int temp = s.top();
s.pop();
temp = s.top() * temp;
s.pop();
s.push(temp);
}
else if(tokens[i] == "/"){
int temp = s.top();
s.pop();
temp = s.top() / temp;
s.pop();
s.push(temp);
}
else{
s.push(stoi(tokens[i])); // stoi 用于将字符串转为整数
}
}
return s.top();
}
};
如果tokens[i]
是一个字符(即std::string
的大小为1),那么你可以使用tokens[i][0] - '0'
来将其转换为整数。这种方法是基于字符的ASCII值,因为字符'0'
到'9'
在ASCII表中是连续的。
关于stoi
:
stoi
是C++标准库中的一个函数,用于将字符串转换为整数。
基本用法:
string str1 = "42";
int num = stoi(str1);
cout << num; // 输出: 42
函数签名是:
int stoi (const string& str, size_t* idx = 0, int base = 10);
str
:要转换的字符串。idx
:一个指针,将在转换停止时设置为字符串中第一个不是数字的字符的位置。base
:数的基数,例如10表示十进制,16表示十六进制等。默认值为10。
其他类似的函数:
stol
和stoll
: 分别将字符串转换为long
和long long
整数。stof
: 将字符串转换为float
。stod
: 将字符串转换为double
。stold
: 将字符串转换为long double
。stoul
和stoull
: 分别将字符串转换为unsigned long
和unsigned long long
整数。
这些函数都在<string>
头文件中,并属于std
命名空间。
如果你尝试将不包含有效数字的字符串(如"adbc")使用stoi
函数转换,将会抛出一个std::invalid_argument
异常。
例如,以下代码:
std::string str = "adbc";
try {
int num = std::stoi(str);
std::cout << num << std::endl;
} catch (const std::invalid_argument& e) {
std::cout << "Invalid argument: " << e.what() << std::endl;
}
将会输出:
Invalid argument: stoi
表示因为字符串"adbc"无法转换为整数,所以stoi
函数抛出了异常。