题目1:232. 用栈实现队列
思路:用两个栈模拟队列
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
public MyQueue() {
stackIn=new Stack<>();
stackOut=new Stack<>();
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
if (stackOut.isEmpty()){
while (!stackIn.isEmpty()){
stackOut.push(stackIn.pop());
}
}
return stackOut.pop();
}
public int peek() {
//peek是获取元素,可以服用pop方法 pop完在放进去
int pop=this.pop();
stackOut.push(pop)
return pop;
}
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
}
题目2:225. 用队列实现栈
思路:用两个队列模拟
class MyStack {
//q1作为主要的队列,其元素排列顺序和出栈顺序相同
Queue<Integer> q1 = new ArrayDeque<>();
//q2仅作为临时放置
Queue<Integer> q2 = new ArrayDeque<>();
public MyStack() {}
public void push(int x) {
while(q1.size()>0){
q2.add(q1.poll());
}
q1.add(x);
while (q2.size() > 0) {
q1.add(q2.poll());
}
}
public int pop() {
return q1.poll();
}
public int top() {
return q1.peek();
}
public boolean empty() {
return q1.empty();
}
}
题目3:20. 有效的括号
思路:分三种情况,1.如果左边的括号多了会导致栈多出元素,2.中间括号不匹配,3.如果右边的括号多了会导致栈空。要考虑这三点,为了好处理遇到’(‘,向栈内push’)'。
class Solution {
public boolean isValid(String s) {
Stack<Character> stack=new Stack<>();
char[] chars=s.toCharArray();
for(int i=0;i<chars.length;i++){
if(chars[i]=='('){
stack.push(')');
}else if(chars[i]=='{'){
stack.push('}');
}else if(chars[i]=='['){
stack.push(']');
//判断三种情况 2.中间不匹配 3.右多 栈空
}else if(stack.isEmpty()||stack.peek()!=chars[i]){
return false;
}else{
stack.pop();
}
}
//1.左多 栈剩元素
return stack.isEmpty();
}
}
题目4:1047. 删除字符串中的所有相邻重复项
思路:用栈匹配,再反转字符串
class Solution {
public String removeDuplicates(String s) {
Stack<Character> stack=new Stack<>();
char[] chars=s.toCharArray();
for(int i=0;i<chars.length;i++){
if(stack.isEmpty()||stack.peek()!=chars[i]){
stack.push(chars[i]);
}else{
stack.pop();
}
}
//反转剩余字符串
String str = "";
while (!stack.isEmpty()) {
str = stack.pop() + str;
}
return str;
}
}
题目5:150. 逆波兰表达式求值
思路:靠栈,如果是"+“,”-“,”*“,”/"就从栈中弹出元素,把计算好的结果再放入栈中,最后计算完栈中还有一个元素就是结果。
class Solution {
public int evalRPN(String[] tokens) {
Stack<String> stack=new Stack<>();
for(int i=0;i<tokens.length;i++){
if(tokens[i].equals("+")){
Integer t1=Integer.valueOf(stack.pop());
Integer t2=Integer.valueOf(stack.pop());
stack.push(t1+t2+"");
}else if(tokens[i].equals("-")){
Integer t1=Integer.valueOf(stack.pop());
Integer t2=Integer.valueOf(stack.pop());
stack.push(t2-t1+"");
}else if(tokens[i].equals("*")){
Integer t1=Integer.valueOf(stack.pop());
Integer t2=Integer.valueOf(stack.pop());
stack.push(t2*t1+"");
}else if(tokens[i].equals("/")){
Integer t1=Integer.valueOf(stack.pop());
Integer t2=Integer.valueOf(stack.pop());
stack.push(t2/t1+"");
}else{
stack.push(tokens[i]);
}
}
return Integer.valueOf(stack.pop());
}
}
题目6:239. 滑动窗口最大值
思路:维护一个单调递增队列,得自己写。
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 1) {
return nums;
}
int len = nums.length - k + 1;
//存放结果元素的数组
int[] res = new int[len];
int num = 0;
MyQueue myQueue = new MyQueue();
//先将前k的元素放入队列 因为结果数组的长度与遍历长度不一样 所以前k个单独算
for (int i = 0; i < k; i++) {
myQueue.add(nums[i]);
}
res[num] = myQueue.peek();
num++;
for (int i = k; i < nums.length; i++) {
//维护滑动窗口处最大值,当要移除的元素与最大值相等时,需移除最大值
myQueue.poll(nums[i - k]);
//滑动窗口加入最后面的元素
myQueue.add(nums[i]);
//记录最大值
res[num] = myQueue.peek();
num++;
}
return res;
}
}
class MyQueue {
Deque<Integer> deque = new LinkedList<>();
//如果要移除的元素==队列中最大值就移除,维护滑动窗口中的最大值
void poll(int val) {
if (!deque.isEmpty() && val == deque.peek()) {
deque.poll();
}
}
//添加元素时,如果要添加的元素大于队列尾部时,一直弹到不大于为止
void add(int val) {
while (!deque.isEmpty() && val > deque.getLast()) {
deque.removeLast();
}
deque.add(val);
}
//队列队顶元素始终为最大值
int peek() {
return deque.peek();
}
}
题目7:347. 前 K 个高频元素
思路:用map记录元素和出现次数,在用stream流对出现次数排序倒序排列,限制前k个
class Solution {
public int[] topKFrequent(int[] nums, int k) {
//key为数组元素值,val为对应出现次数
Map<Integer,Integer> map = new HashMap<>();
for(int i=0;i<nums.length;i++){
Integer value=map.get(nums[i]);
if(map.get(nums[i])!=null){
value++;
map.put(nums[i],value);
}else{
map.put(nums[i],1);
}
}
return map.entrySet().stream()
.sorted(Comparator.comparingInt(entry -> -entry.getValue()))
.limit(k)
.mapToInt(entry -> entry.getKey())
.toArray();
}
}