备战秋招day6

算法

232. 用栈实现队列

class MyQueue {

    Stack<Integer> in;
    Stack<Integer> out;

    //构造器
    public MyQueue() {
        in = new Stack<>();
        out = new Stack<>();
    }
    //入队到末尾
    public void push(int x) {
        in.push(x);
    }

    //出队
    public int pop() {
        //先进先出
        //in的元素放入out里面然后pop就能达到先进先出的目的,元素顺序都被调转了
        change();
        return out.pop();
    }

    //返回队列开头元素
    public int peek() {
        change();
        return out.peek();
    }

    //判空
    public boolean empty() {
        return in.isEmpty() && out.isEmpty();
    }

    //写一个方法:做将元素从in转到out
    public void change(){
        //出队的首要条件是:out为空
        if(!out.isEmpty()) return;
        while(!in.isEmpty()){
            out.push(in.pop());
        }
    }
}

225. 用队列实现栈

class MyStack {
    Deque<Integer> que;

    public MyStack() {
        que = new ArrayDeque<>();
    }
    
    //每次都加到最前面(只能使用标准操作)
    public void push(int x) {
        que.push(x);
        int size = que.size();
        //我们无需移动刚进来的数
        while(size-- >1){
            que.push(que.pop());
        }
    }
    //先进后出:由于我们的添加操作,导致最先进来的一定在最左边
    public int pop() {
        return que.pop();
    }
    
    public int top() {
        return que.peek();
    }
    
    public boolean empty() {
        return que.isEmpty();
    }
}

20. 有效的括号

class Solution {
    public boolean isValid(String s) {
        //用栈来做:思路就跟消消乐一样
        Stack<Character> stack = new Stack<>();
        int len = s.length();
        for(int i = 0;i<len;i++){
            char ch = s.charAt(i);
            if(ch == '('){
                stack.push(')');
            }else if(ch == '['){
                stack.push(']');
            }else if(ch == '{'){
                stack.push('}');
            }else if(stack.isEmpty() || stack.peek()!=ch){
                return false;
            }else{
                stack.pop();
            }
        }
        return stack.isEmpty();
    }
}

1047. 删除字符串中的所有相邻重复项

class Solution {
    public String removeDuplicates(String s) {
        //依旧用栈来做
        Stack<Character> stack = new Stack<>();
        int len = s.length();
        for(int i = 0;i<len;i++){
            char ch = s.charAt(i);
            //相同则出栈
            if(!stack.isEmpty() && stack.peek()==ch){
                char ca = stack.pop();
                //System.out.println("pop: " + ca + ": " + i);
                continue;
            }
            stack.push(ch);
            //System.out.println("push: " + ch + ": " + i);
        }
        String res = "";
        while(!stack.isEmpty()){
            res = stack.pop() + res;
            //System.out.println(res);
        }
        return res;
    }
}

150. 逆波兰表达式求值

class Solution {
    public int evalRPN(String[] tokens) {
        //很显然使用栈来解决
        Stack<Integer> stack = new Stack<>();
        for(String s : tokens){
            if(s.equals("+")){
                stack.push(stack.pop() + stack.pop());
            }else if(s.equals("-")){
                stack.push(-stack.pop() + stack.pop());
            }else if(s.equals("*")){
                stack.push(stack.pop() * stack.pop());
            }else if(s.equals("/")){
                int temp1 = stack.pop();
                int temp2 = stack.pop();
                stack.push(temp2 / temp1);
            }else{
                //转换值
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }
}

239. 滑动窗口最大值

class Solution {
    //为什么说这道题是单调队列?
    //很明显,在几个窗口里面,我们需要维护这些窗口里面的一个单调值(这道题来说就是最大值)
    //利用单调队列来做,可以实现入队出队,以及维护我们需要的这个单调情况这些操作

    //而java里面可以通过双端队列来实现
    public int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Integer> deque = new LinkedList<>();
        int n = nums.length;
        //有n个数,只能看到k个数字,res只需要最多n-k个即可
        int[] res = new int[n-k+1];
        int index = 0;
        //由于我们不好直接把值放入,因此选择把下标放入队列中
        for(int i = 0;i<n;i++){
            //不在窗口内的元素就要出队了
            while(!deque.isEmpty() && deque.peek() < i-k+1){
                deque.poll();
            }
            //与队列内的元素进行比较,保证单调递增
            while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]){
                deque.pollLast();
            }
            deque.offer(i);
            //开始记录最值
            if(i>=k-1){
                res[index++] = nums[deque.peek()];
            }
        }
        return res;
    }
}

347. 前 K 个高频元素

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //利用Map存元素和次数,然后利用大顶堆或小顶堆来实现
        Map<Integer,Integer> map = new HashMap<>();
        for(int i : nums){
            map.put(i,map.getOrDefault(i,0)+1);
        }
        //大顶堆的写法
        PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2) -> pair2[1] - pair1[1]);
        for(Map.Entry<Integer,Integer> entry : map.entrySet()){
            pq.add(new int[]{entry.getKey(),entry.getValue()});
        }
        int[]res = new int[k];
        for(int i = 0;i<k;i++){
            res[i] = pq.poll()[0];
        }
        return res;
    }
}

今日算法思考

其余的题目基本上使用栈即可解决,思想也比较简单,大致上就是通过栈的特性,达到类似相消的效果。

值得一说的就是“滑动窗口最大值”这道题

我们通过队列来模拟窗口,当遍历达到窗口长度的时候,就得准备挪动窗口,我们要边挪动窗口边找到窗口内最大值,而队列内维护是下标。


补充知识点

MySQL

对行级锁/记录锁的理解

分类:行锁,间隙锁,临键锁

这里会涉及到InnoDB引擎解决幻读问题,使用到间隙锁和临键锁来解决幻读问题

存储引擎

InnoDB如何解决幻读问题

MyISAM和InnoDB区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值