牛客top100 - 自刷打卡day4+day5 - 栈/堆/队列

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


堆/栈/队列

堆/栈/队列

BM42用两个栈实现队列

用两个栈实现队列

思路简单41.49%

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        while(!stack1.empty()) {
            stack2.push(stack1.pop());
        }
        int top = stack2.pop();
        while(!stack2.empty()){
            stack1.push(stack2.pop());
        }
        return top;
    }
}

BM43包含min函数的栈

包含min函数的栈

思路简单35.20%

  • 模拟一个最小栈, 放原栈的最小值
  • 注意min>=node, 少了等于号有个案例通不过
import java.util.Stack;

public class Solution {
    int min = 10000;
    Stack<Integer> minStack = new Stack<>();
    Stack<Integer> stack = new Stack<>();
    public void push(int node) {
        stack.push(node);
        if (min >= node) { // 注意这里的>=
            min = node;
            minStack.push(min);
        } else {
            minStack.push(minStack.peek());
        }
    }

    public void pop() {

        stack.pop();
        minStack.pop();
    }

    public int top() {
        return stack.peek();
    }

    public int min() {
        return minStack.peek();
    }
}

BM44有效括号序列

有效括号序列

思路简单33.66%

  • 栈的思维, 判断最后栈是否为空
import java.util.*;


public class Solution {
    /**
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    public boolean isValid (String s) {
        // write code here
        char[] arr = s.toCharArray();
        Stack<Character>st = new Stack<>();
        for(int i = 0; i < arr.length; i++) {
            if(arr[i] == '(') {
                st.push(')');
            }else if(arr[i] == '[') {
                st.push(']');
            }else if(arr[i] == '{'){
                st.push('}');
            }else{
                if(st.empty() || arr[i] != st.peek()){
                    return false;
                }
                st.pop();
            }
        }
        return st.empty();

    }
}

BM45滑动窗口的最大值

滑动窗口的最大值

思路较难27.53%

import java.util.*;
public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size) {
        if(size > num.length || size == 0) return new ArrayList<>();
        int left = 0;
        int right = size - 1;
        ArrayList<Integer> res = new ArrayList<>();
        while (right < num.length) {
            PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
                public int compare(Integer o1, Integer o2) {
                    return o2 - o1;
                }
            });
            //写的时候注意这里是i < size+left 或者i <= right , 变化的下标边界
            for (int i = left; i <= right; i++) {
                queue.offer(num[i]);
            }
            res.add(queue.peek());
            left++;
            right++;
        }
        return res;
    }
}

BM46最小的K个数

最小的K个数

思路中等27.78%

  • topK, 秒
  • 维护高度为K的堆, 时间复杂度是nlog(K)
import java.util.*;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> res = new ArrayList<>();
        if(k == 0) return res;
        //最小k 建立大堆
        PriorityQueue<Integer> queue = new PriorityQueue<>(k, new Comparator<Integer>(){
            public int compare(Integer o1, Integer o2){
                return o2 - o1;
            }
        });
        for(int i = 0; i < k; i++) {
            queue.offer(input[i]);
        }
        for(int i = k; i < input.length; i++) {
            if(input[i] < queue.peek()){
                queue.poll();
                queue.offer(input[i]);
            }
        }
        for(int i = 0; i < k; i++) {
            res.add(queue.poll());
        }
        return res;
    }
}

BM47寻找第K大

寻找第K大

思路中等28.81%

import java.util.*;

public class Solution {
    public int findKth(int[] a, int n, int K) {
        if (K == 0 || K > n) {
            return 0;
        }
        // write code here
        //第K大的数
        
        PriorityQueue<Integer> q = new PriorityQueue<>(K, new Comparator<Integer>() {
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        for(int i = 0; i < K; i++) {
            q.offer(a[i]);
        }
        for(int i = K; i < a.length; i++) {
            if(a[i] > q.peek()){
                q.poll();
                q.offer(a[i]);
            }
        }
        return q.peek();


    }
}

BM48数据流中的中位数

数据流中的中位数

思路中等29.63%

  • 排序
import java.util.*;

public class Solution {
    public ArrayList<Integer> arr = new ArrayList<>();
    public void Insert(Integer num) {
        if(arr.isEmpty()) {
            arr.add(num);
        }else{
            int i = 0;
            for(;i < arr.size() ; i++) {
                if(num <= arr.get(i)){
                    break;
                }
            }
            arr.add(i, num);
        }
    }

    public Double GetMedian() {
        int n = arr.size();
        if(n % 2 == 1){
            return (double)arr.get(n / 2);
        }else{
            double a = arr.get(n / 2 - 1);

            double b = arr.get(n / 2);
            return (a + b) / 2;
        }
    }


}

  • 维护两个堆, 学习这种思想, 一个大根堆, 一个小根堆
  • 如果是奇数个, 选取一个堆的堆顶作为返回中位数
  • 如果偶数个, 选取两个堆的堆顶平均值作为返回中位数
import java.util.*;
public class Solution {
    //eg 1 2 3 4 5 6 7
    //max : 1 2 3 4
    //min : 5 6 7
    //返回4
    //我们定义奇数个返回前面数据的最大值
    //        偶数个返回前面数据最大值和后面数据最小值的平均值
    PriorityQueue<Integer> max = new PriorityQueue<>((o1, o2)->{
        return o2 - o1;
    });//大根堆  放前面的数据
    PriorityQueue<Integer> min = new PriorityQueue<>();//小根堆  放后面的数据
    public void Insert(Integer num) {
        //数据进入大根堆
        max.offer(num);
        //将大根堆的最大值给小根堆, (最大值后移到后面数据的堆中)
        min.offer(max.poll());
        //发现后面数据的堆数量 大于 前面数据的堆数量了
        if (min.size() > max.size()) {
            //数据前移到前面数据的堆中
            max.offer(min.poll());
        }
    }

    public Double GetMedian() {
        if (max.size() > min.size()) {
            return (double) max.peek();
        } else {
            return (double)(min.peek() + max.peek()) / 2;
        }
    }


}

BM49表达式求值

表达式求值

思路中等43.35%

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    public int solve (String s) {
        s = s.trim();
        Stack<Integer> stack = new Stack<>();
        char sign = '+';
        char[] ch = s.toCharArray();
        int num = 0;
        for(int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if(Character.isDigit(c)){
                num = num * 10 + c - '0';
            }
            //这时候调用solve, 计算()内的数据值
            //双括号情况下, 下面写法无法正确计算
            // if(c == '('){
            //     int oldI = i;
            //     while(c != ')'){
            //         i++;
            //         c = ch[i];
            //     }
            //     num = solve(s.substring(oldI+1, i ));
            // }
            if(c == '(') {
                int oldI = i++;
                int kuohao = 1;
                //这个值用来计算括号数, 我们计(为一个正括号 , ) 为一个负括号, 当kuohao==0的时候
                //才表示一整个括号内的值计算
                while(kuohao > 0) {
                    if(ch[i] == '(') {
                        kuohao++;
                    }
                    if(ch[i] == ')'){
                        kuohao--;
                    }
                    i++;
                }
                num = solve(s.substring(oldI + 1, i - 1));
                i = i - 1;
            }
            if(!Character.isDigit(c) || i == ch.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;
                sign = c;
            }
            
        }
        int ans = 0;
        while(!stack.isEmpty()){
            ans += stack.pop();
        }
        return ans;
        // write code here
    }
}

陷入了纠结的境地, 不知道如何描述自己的心情
如果人有分身术就好了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值