堆栈队列排序——面试必刷TOP101

堆/栈/队列/排序

BM42 用两个栈实现队列

import java.util.Stack;

public class Solution {
    Stack<Integer> s1 = new Stack<Integer>();
    Stack<Integer> s2 = new Stack<Integer>();
    
    public void push(int node) {
        s1.push(node);
    }
    
    public int pop() {
        if(s2.isEmpty()){
            while(!s1.isEmpty()) s2.push(s1.pop());
        }
        return s2.pop();
    }
}

BM43 包含min函数的栈

import java.util.Stack;

public class Solution {
    Stack<Integer> s1=new Stack<>();
    Stack<Integer> s2=new Stack<>();
    
    public void push(int node) {
        s1.push(node);
        if(s2.isEmpty()||s2.peek()>=node) s2.push(node);
    }
    
    public void pop() {
        if(s1.pop().equals(s2.peek())) s2.pop();
    }
    
    public int top() {
        return s1.peek();
    }
    
    public int min() {
        return s2.peek();
    }
}

BM44 有效括号序列

import java.util.*;


public class Solution {

    public boolean isValid (String s) {
        Stack<Character> stack=new Stack<>();
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='(') stack.push(')');
            else if(s.charAt(i)=='[') stack.push(']');
            else if(s.charAt(i)=='{') stack.push('}');
            else if(stack.isEmpty() || s.charAt(i)!=stack.pop()) return false;
        }
        return stack.isEmpty();
    }
}

BM45 滑动窗口的最大值

import java.util.*;
public class Solution {
    ArrayList<Integer> res=new ArrayList<>();
    public ArrayList<Integer> maxInWindows(int [] num, int k) {
        if(num.length==0|| k==0) return res;
        Deque<Integer> deque=new LinkedList<>();//双端队列
        for(int i=0;i<k;i++){
            while(!deque.isEmpty() && deque.peekLast()<num[i]) deque.removeLast();
            deque.addLast(num[i]);
        }
        res.add(deque.peekFirst());
        for(int i=k;i<num.length;i++){
            if(num[i-k]==deque.peekFirst()) deque.removeFirst();
            while(!deque.isEmpty() && deque.peekLast()<num[i]) deque.removeLast();
            deque.addLast(num[i]);
            res.add(deque.peekFirst());
        }
        return res;
    }
}

BM46 最小的K个数

import java.util.ArrayList;

class Solution {
    ArrayList<Integer> res=new ArrayList<>();
    public ArrayList<Integer> GetLeastNumbers_Solution(int[] arr, int k) {
        if(k>arr.length || k==0 || arr==null) return res;
        quickSort(arr,k,0,arr.length-1);
        return res;
    }
    private void quickSort(int[] arr,int k,int l,int r){
        int i=l,j=r;
        while(i<j){
            while(i<j&&arr[j]>=arr[l])j--;
            while(i<j&&arr[i]<=arr[l])i++;
            swap(arr,i,j);
        }
        swap(arr,i,l);
        if(i>k)  quickSort(arr,k,l,i-1);
        else if(i<k)  quickSort(arr,k,i+1,r);
        else{
            for(int m=0;m<k;m++)
                res.add(arr[m]);
        }
    }
    private void swap(int[] arr,int i,int j){
        if (i == j)return;
        int tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }
}

BM47 寻找第K大

import java.util.*;

public class Solution {
    public int findKth(int[] nums,int n, int k) {
        int tar=n-k;
        int left=0,right=n-1;
        while(true){
            int index = partition(nums,left,right);
            if(index < tar) left=index+1;
            else if(index > tar) right=index-1;
            else return nums[index];
        }

    }
    public int partition(int[] nums,int l,int r){
        int picked=(int)(Math.random()*(r-l+1))+l;
        swap(nums,picked,l);
        
        int j=l;
        for(int i=l+1;i<=r;i++){
            if(nums[i]<nums[l]){
                j++;
                swap(nums,j,i);
            }
        }
        swap(nums,j,l);
        return j;
    }
    public void swap(int[] nums,int a,int b){
        int tmp=nums[a];
        nums[a]=nums[b];
        nums[b]=tmp;
    }
}

BM48 数据流中的中位数

import java.util.PriorityQueue;

public class Solution {

   PriorityQueue<Integer> A=new PriorityQueue<>();
   PriorityQueue<Integer> B=new PriorityQueue<>((x,y)->(y-x));
    
    public void Insert(Integer num) {
        if(A.size()!=B.size()){
            A.add(num);
            B.add(A.poll());
        }else{
            B.add(num);
            A.add(B.poll());
        }
    }

    public Double GetMedian() {
        return A.size()!=B.size()?A.peek()/1.0:(A.peek()+B.peek())/2.0;
    }

}

BM49 表达式求值

import java.util.*;


public class Solution {
    public int solve (String s) {
        Stack<Integer> stack = new Stack<>();//初始化栈
        int num= 0;//默认数字
        char sign = '+';//默认的第一个数字前的运算符为 + 
        char[] arr = s.toCharArray();//字符串转化字符数组
        for(int i = 0;i<s.length();i++){//对字符数组每个元素遍历
            char c = arr[i];
            
            if (c == ' ') continue;
            
            if(c == '('){//是否为左括号
                int j = i + 1;
                int counterPar = 1;//默认是1对括号
                while(counterPar > 0){//统计是否存在括号嵌套的情况
                    if(arr[j] == '(') counterPar++;
                    else if(arr[j] == ')')counterPar--;
                    //向后直到找到右括号
                    j++;
                }
                //遇到左括号递归求这个括号里面表达式的值
                //就是求左括号 到 右括号 之间 表达式的 值,返回值为 number,下面接着进栈
                num  = solve(s.substring(i + 1,j - 1));
                //下一次就要从 j 开始,因为后面还有一个 i ++;
                i = j - 1;
            }
            
            if(Character.isDigit(c)) num = num * 10 + c - '0';//是否为数字,是数字就求完整的数字值,每次循环都进这个分支,直到出现运算符
           
            if( ! Character.isDigit(c) || i == s.length() - 1){ //不是数字 或者 为最后一个字符
                if(sign == '+') stack.push(num);//是 + 先把 数字 压栈,等会全部数字出栈之和即为所求
                else if(sign == '-') stack.push( -1 * num);//是 - 压栈该数字的相反数
                else if(sign == '*') stack.push(stack.pop() * num);//是 * ,弹栈算出结果,在压栈
                else if(sign == '/') stack.push(stack.pop() / num);//是 / ,弹栈算出结果,在压栈
                num = 0; //每次结束,数字恢复默认值
               // 遇到运算符时或者到表达式末尾时,就去计算上一个运算符并把计算结果push进栈,然后保存新的运算符
                //运算符为 当前压栈数字 前面近邻的那个
                sign = c;
                //如果是负数 在 表达式的最前面 ,会先压栈 +0,然后在记录当前 负号,开始接下来的数字
            }
        }
        int sum = 0;        //结果
        while(!stack.isEmpty()){
            sum += stack.pop();
        }
        return sum;
    }
}

BM20 数组中的逆序对

public class Solution {
    int[] arr,assist;
    public int InversePairs(int [] arr) {
        this.arr=arr;
        assist=new int[arr.length];
        return merge(0,arr.length-1);
    }
    private int merge(int l,int r){
        if(l>=r) return 0;
        int m=(l+r)/2;
        int res=merge(l,m)+merge(m+1,r);
        for(int k=l;k<=r;k++){
            assist[k]=arr[k];
        }
        int i=l,j=m+1;
        for(int k=l;k<=r;k++){
            if(i==m+1){
                arr[k]=assist[j++];
            }else if(j==r+1 || assist[i]<=assist[j]){
                arr[k]=assist[i++];
            }else{
                arr[k]=assist[j++];
                res=(res+m-i+1)%1000000007;
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值