代码随想录算法训练营第11天 | 栈与队列2

20.有效括号

题目: 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
链接: https://leetcode.cn/problems/valid-parentheses
思路: 遍历字符串,遇到左括号的时候把右括号放入栈里,遇到右括号的时候判断是不是和栈顶元素相匹配,如果匹配就弹出,不匹配(情况3)就返回false,最后看栈里是否有剩余元素(情况1);字符串尚未遍历完,栈已经为空(情况2)。
三种不匹配的情况:

  1. 有左括号找不到右括号,例如:([{}]()
  2. 有右括号找不到左括号,例如:[{}]())))
  3. 左右括号不匹配,例如:[{(}}]
class Solution {
public:
	bool isValid(string s) {
		if(s.size() % 2 != 0){
			return false;
		}
	
		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('}');
			}
			
			//出栈的情况
			//栈为空:有多余的右括号;栈顶右括号元素和下一个右括号元素不匹配
			else if(st.empty() || s[i] != st.top()){
				return false;
			}
			else{
				st.pop();
			}
		}
		if(st.empty()){
			return true;
		}
		else{
			return false;
		}
	}
};

1047. 删除字符串中的所有相邻重复项

题目: 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
链接: https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string
思路: 使用一个栈存放遍历过的元素,每次遍历的时候都判断一下当前元素和栈顶元素是否一致,若一致就消除,若不一致就存入栈中继续遍历。

class Solution {
public:
	string removeDuplicates(string s) {
	stack<char> st;
	for(int i = 0; i < s.size(); ++i){
		if(st.empty() || s[i] != st.top()){
			st.push(s[i]);
		}
		else{
			st.pop();
		}
	}
	string res = "";
	while(!st.empty()){
		res += st.top();
		st.pop();
	}
	reverse(res.begin(), res.end());
	return res;
	}
};

150.逆波兰表达式求值

题目: 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。
每个操作数(运算对象)都可以是一个整数或者另一个表达式。
两个整数之间的除法总是 向零截断 。
表达式中不含除零运算。
输入是一个根据逆波兰表示法表示的算术表达式。
答案及所有中间计算结果可以用 32 位 整数表示。

逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:
去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
链接: https://leetcode.cn/problems/evaluate-reverse-polish-notation
思路: 如果把已知字符串用二叉树表示,我们正常看到的表达式是“左中右”的中序遍历表达式,波兰表达式就是一种“左右中”的后序遍历表达式。
遍历vector<string>,遇到数字就推入栈中,遇到运算符就计算一下。

class Solution {
public:
	int evalRPN(vector<string>& tokens) {
		stack<int> st;
		for(int i = 0; i < tokens.size(); ++i){
			if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){
				int temp1 = st.top();
				st.pop();	
				int temp2 = st.top();	
				st.pop();	
				if(tokens[i] == "+"){	
					st.push(temp1 + temp2);	
				}	
				if(tokens[i] == "-"){	
					st.push(temp2 - temp1);	
				}	
				if(tokens[i] == "*"){	
					st.push(temp1 * temp2);	
				}	
				if(tokens[i] == "/"){	
					st.push(temp2 / temp1);	
				}	
			}	
			else{	
				st.push(stoi(tokens[i]));	
			}	
		}	
		return st.top();	
	}
};
第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值