1. 有效的括号 题目链接
- 题目要求:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

- 代码及思路
- 经典的使用栈来解决的问题
- 遇到左括号将对应的右括号入栈,遇到右括号则与栈顶元素进行比较,若不同则直接返回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 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。

- 使用一个单调递增的双向队列解决问题
- 遍历数组元素,在每一次遍历中当窗口大小大于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] 的输入。

- 代码及思路
- 使用栈解决问题,分别使用一个栈存储数字和之前的字符串
- 遇到‘[’将数字和当前字符串入栈,遇到’]'则将之前的数字和字符串取出和当前的字符串做拼接
- 代码
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 。

- 代码及思路
- 使用栈解决,先遍历链表将所有节点的值压入栈中
- 再次从头遍历链表,每次将节点值与栈顶元素相比较
- 代码
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 来代替。

- 代码及思路
- 使用一个单调递减栈来存储温度的下标值
- 遍历温度数组,然后循环找出栈中小于当前温度的温度下标值,更新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;}
}