博客记录-day138-力扣+场景题

60 阅读4分钟

一、力扣

1、小行星碰撞

735. 小行星碰撞

image.png

class Solution {
    public int[] asteroidCollision(int[] asteroids) {
        // 使用双端队列模拟栈结构,存储最终存活的小行星
        Deque<Integer> stack = new ArrayDeque<>();
        
        // 遍历每个小行星
        for (int asteroid : asteroids) {
            boolean alive = true; // 标记当前小行星是否存活
            
            // 当当前小行星向左移动,且栈不为空且栈顶小行星向右移动时,处理碰撞
            while (alive && asteroid < 0 && !stack.isEmpty() && stack.peek() > 0) {
                // 判断栈顶小行星是否会被当前小行星摧毁(栈顶绝对值是否小于当前绝对值)
                alive = stack.peek() < -asteroid;
                
                // 如果栈顶小行星被摧毁,则弹出栈顶元素,继续检查下一个栈顶
                if (stack.peek() <= -asteroid) {
                    stack.pop();
                }
            }
            
            // 若当前小行星存活,则压入栈中
            if (alive) {
                stack.push(asteroid);
            }
        }
        
        // 将栈中元素转换为数组(需逆序输出)
        int len = stack.size();
        int[] result = new int[len];
        for (int i = len - 1; i >= 0; i--) {
            result[i] = stack.pop();
        }
        
        return result;
    }
}

2、字符串解码

394. 字符串解码

image.png

class Solution {
    public String decodeString(String s) {
        // 使用两个栈分别保存数字和字符串片段
        ArrayDeque<Integer> stnum = new ArrayDeque<>();  // 存储重复次数
        ArrayDeque<StringBuilder> stsb = new ArrayDeque<>(); // 存储之前的字符串结果
        StringBuilder ans = new StringBuilder(); // 当前构建的字符串
        int k = 0; // 临时存储当前处理的数字

        for (int i = 0; i < s.length(); i++) {
            char temp = s.charAt(i);
            
            if (Character.isDigit(temp)) {
                // 处理多位数字,例如将 '12' 转换为整数12
                k = k * 10 + (temp - '0');
            } else if (temp == '[') {
                // 遇到左括号,保存当前状态到栈中
                stnum.push(k);       // 保存当前重复次数
                stsb.push(ans);      // 保存当前已构建的字符串
                k = 0;               // 重置数字计数器
                ans = new StringBuilder(); // 清空当前字符串,准备处理括号内内容
            } else if (temp == ']') {
                // 遇到右括号,弹出栈顶元素拼接结果
                int count = stnum.pop();   // 获取重复次数
                StringBuilder col = stsb.pop(); // 获取之前的字符串片段
                
                // 将当前括号内的内容重复count次并拼接到col
                while (count > 0) {
                    col.append(ans);
                    count--;
                }
                ans = col; // 更新ans为拼接后的结果
            } else {
                // 普通字符直接追加到当前结果
                ans.append(temp);
            }
        }
        return ans.toString();
    }
}

3、二叉树的最近公共祖先

236. 二叉树的最近公共祖先

image.png

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null||root==p||root==q) return root;
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);
        if(left!=null&&right!=null) return root;
        if(left==null) return right;
        return left;
    }
}

4、二叉树的层序遍历 II

107. 二叉树的层序遍历 II

image.png

class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> res=new ArrayList<>();
        ArrayDeque<TreeNode> p=new ArrayDeque<>();
        if(root!=null) p.offer(root);
        while(!p.isEmpty()){
            int len=p.size();
            List<Integer> path=new ArrayList<>();
            for(int i=0;i<len;i++){
                TreeNode fir=p.poll();
                path.add(fir.val);
                if(fir.left!=null) p.offer(fir.left);
                if(fir.right!=null) p.offer(fir.right);
            }
            res.add(0,path);
        }
        return res;
    }
}

5、二叉树的右视图

199. 二叉树的右视图

image.png

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res=new ArrayList<>();
        ArrayDeque<TreeNode> queue=new ArrayDeque<>();
        if(root!=null) queue.offer(root);
        while(!queue.isEmpty()){
            int s=queue.size();
            for(int i=0;i<s;i++){
                TreeNode temp=queue.poll();
                if(temp.left!=null) queue.offer(temp.left);
                if(temp.right!=null) queue.offer(temp.right);
                if(i==s-1){
                    res.add(temp.val);
                }
            }
        }
        return res;
    }
}

二、语雀-场景题

1、为什么MySQL用B+树,MongoDB用B树?

✅为什么MySQL用B+树,MongoDB用B树?

image.png

image.png

2、高并发的库存系统,在数据库扣减库存,怎么实现?

✅高并发的库存系统,在数据库扣减库存,怎么实现?

image.png

1. 排队

image.png

image.png

2. 拆分

image.png

3. 合并

image.png

3、MySQL热点数据更新会带来哪些问题?

✅MySQL热点数据更新会带来哪些问题?

image.png

image.png

4、和外部机构交互如何防止被外部服务不可用而拖垮

✅和外部机构交互如何防止被外部服务不可用而拖垮

1. 异步交互

image.png

2. 超时机制

image.png

3. 限流降级熔断

image.png

5、一亿个QQ号,判断一个值是否存在

✅在100M内存下存储一亿个整数,其范围在1到2亿,如何快速判断给定到一个整数值是否存在?

image.png image.png

6、如何实现缓存的预热?

✅如何实现缓存的预热?

1. 启动过程中预热

image.png

2. 定时任务

image.png

3. 用时加载

image.png

4. 缓存加载器

image.png

7、如何实现百万级数据从Excel导入到数据库?

✅如何实现百万级数据从Excel导入到数据库?

image.png

image.png

1. 错误处理

image.png

8、一次RPC请求,客户端显示超时,但是服务端不超时,可能是什么原因?

✅一次RPC请求,客户端显示超时,但是服务端不超时,可能是什么原因?

image.png

image.png

9、为什么不建议使用MQ实现订单到期关闭?

✅为什么不建议使用MQ实现订单到期关闭?

image.png