一、力扣
1、小行星碰撞
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、字符串解码
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、二叉树的最近公共祖先
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
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、二叉树的右视图
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树?
2、高并发的库存系统,在数据库扣减库存,怎么实现?
1. 排队
2. 拆分
3. 合并
3、MySQL热点数据更新会带来哪些问题?
4、和外部机构交互如何防止被外部服务不可用而拖垮
1. 异步交互
2. 超时机制
3. 限流降级熔断
5、一亿个QQ号,判断一个值是否存在
✅在100M内存下存储一亿个整数,其范围在1到2亿,如何快速判断给定到一个整数值是否存在?
6、如何实现缓存的预热?
1. 启动过程中预热
2. 定时任务
3. 用时加载
4. 缓存加载器
7、如何实现百万级数据从Excel导入到数据库?
1. 错误处理
8、一次RPC请求,客户端显示超时,但是服务端不超时,可能是什么原因?
✅一次RPC请求,客户端显示超时,但是服务端不超时,可能是什么原因?