1. 有效的括号 题目链接
- 题目要求:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a486771f41ff42488ffb0532fc05f05e.png)
- 代码及思路
- 经典的使用栈来解决的问题
- 遇到左括号将对应的右括号入栈,遇到右括号则与栈顶元素进行比较,若不同则直接返回false,相同则弹出栈顶元素
- 最后栈为空,表明完全匹配,返回true
- 代码
class Solution {
public boolean isValid(String s) {
if(s.length()%2!=0)return false;
Deque<Character> cache=new LinkedList<>();
for(int i=0;i<s.length();i++){
char c=s.charAt(i);
if(c=='('){
cache.push(')');
}else if(c=='['){
cache.push(']');
}else if (c=='{'){
cache.push('}');
}else if(c==')'){
if(cache.isEmpty()||c!=cache.pop())return false;
}else if(c==']'){
if(cache.isEmpty()||c!=cache.pop())return false;
}else if(c=='}'){
if(cache.isEmpty()||c!=cache.pop())return false;
}
}
return cache.isEmpty();
}
}
2. 滑动窗口最大值 题目链接
- 题目要求:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/dedb4d0173274f8eaa25fa8f9c1a179c.png)
- 使用一个单调递增的双向队列解决问题
- 遍历数组元素,在每一次遍历中当窗口大小大于k时,将队列最初元素出栈
- 循环将小于当前元素的队尾元素出栈
- 当达到窗口大小后开始记录窗口最大值,即为队列队首元素
- 注意队列中存储的是元素的下标值
- 代码
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> cache=new LinkedList<>();
int[] res=new int[nums.length-k+1];
int j=0;
for(int i=0;i<nums.length;i++){
while(!cache.isEmpty()&&i-k+1>cache.getFirst()){
cache.pollFirst();
}
while(!cache.isEmpty()&&nums[i]>nums[cache.getLast()]){
cache.pollLast();
}
cache.offer(i);
if(i-k+1>=0)res[j++]=nums[cache.getFirst()];
}
return res;
}
}
3. 字符串解码 题目链接
- 题目要求:给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7a65ec32527e4782b381698c36214ca9.png)
- 代码及思路
- 使用栈解决问题,分别使用一个栈存储数字和之前的字符串
- 遇到‘[’将数字和当前字符串入栈,遇到’]'则将之前的数字和字符串取出和当前的字符串做拼接
- 代码
class Solution {
public String decodeString(String s) {
Stack<Integer> numbers=new Stack<>();
Stack<String> strs=new Stack<>();
int num=0;
String cur="";
for(int i=0;i<s.length();i++){
char c=s.charAt(i);
if(c>='0'&&c<='9'){
num=num*10+c-'0';
}else if(c=='['){
numbers.push(num);
num=0;
strs.push(cur);
cur="";
}else if(c==']'){
StringBuilder temp=new StringBuilder(strs.pop());
int len=numbers.pop();
for(int j=0;j<len;j++){
temp.append(cur);
}
cur=temp.toString();
}else{
cur=cur+c;
}
}
return cur;
}
}
- 题目要求:给你一个单链表的头节点 head ,请你判断该链表是否为
回文链表。如果是,返回 true ;否则,返回 false 。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f2aa97bc60be47228760cd6d26152027.png)
- 代码及思路
- 使用栈解决,先遍历链表将所有节点的值压入栈中
- 再次从头遍历链表,每次将节点值与栈顶元素相比较
- 代码
class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null)return true;
if(head.next==null)return true;
ListNode cur=head;
Stack<Integer> cache=new Stack<>();
while(cur!=null){
cache.push(cur.val);
cur=cur.next;
}
cur=head;
while(cur!=null){
int num=cache.pop();
if(cur.val!=num)return false;
cur=cur.next;
}
return true;
}
}
- 题目要求:给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55ef2151613f415a8a904389dd4f712e.png)
- 代码及思路
- 使用一个单调递减栈来存储温度的下标值
- 遍历温度数组,然后循环找出栈中小于当前温度的温度下标值,更新answer数组
- 将当前温度的下标入栈
- 代码
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int[] answers=new int[temperatures.length];
Stack<Integer> cache=new Stack<>();
for(int i=0;i<temperatures.length;i++){
while(!cache.isEmpty()&&temperatures[i]>temperatures[cache.peek()]){
int j=cache.pop();
answers[j]=i-j;
}
cache.push(i);
}
return answers;
}
}