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

一、力扣

1、01背包-一和零

【题单】动态规划(入门/背包/状态机/划分/区间/状压/数位/树形/数据结构优化)

背包视频:0-1背包 完全背包【基础算法精讲 18】_哔哩哔哩_bilibili

474. 一和零

java 复制代码
class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        int s = strs.length;
        int[] count = new int[s];
        for (int i = 0; i < s; i++) {
            String temp = strs[i];
            for (char e : temp.toCharArray()) {
                if (e == '0') count[i]++;
            }
        }
        int[][][] dp = new int[m + 1][n + 1][s + 1];
        for (int i = 0; i < s; i++) {
            int num0 = count[i];
            int num1 = strs[i].length() - num0;
            for (int j = 0; j <= m; j++) {
                for (int k = 0; k <= n; k++) {
                    // 初始化为不选当前字符串的情况
                    dp[j][k][i + 1] = dp[j][k][i];
                    if (j >= num0 && k >= num1) {
                        // 选择当前字符串,取较大值
                        dp[j][k][i + 1] = Math.max(dp[j][k][i + 1], dp[j - num0][k - num1][i] + 1);
                    }
                }
            }
        }
        return dp[m][n][s];
    }
}

2、完全背包-零钱兑换

322. 零钱兑换

java 复制代码
class Solution {
    public int coinChange(int[] coins, int amount) {
        int n = coins.length;
        int[][] f = new int[n + 1][amount + 1];
        Arrays.fill(f[0], Integer.MAX_VALUE / 2); // 除 2 防止下面 + 1 溢出
        f[0][0] = 0;
        for (int i = 0; i < n; i++) {
            for (int c = 0; c <= amount; c++) {
                if (c < coins[i]) {
                    f[i + 1][c] = f[i][c];
                } else {
                    f[i + 1][c] = Math.min(f[i][c], f[i + 1][c - coins[i]] + 1);
                }
            }
        }
        int ans = f[n][amount];
        return ans < Integer.MAX_VALUE / 2 ? ans : -1;
    }
}

3、完全背包-零钱兑换 II

518. 零钱兑换 II

java 复制代码
class Solution {
    public int change(int amount, int[] coins) {
        int n = coins.length;
        int[][] f = new int[n + 1][amount + 1];
        f[0][0] = 1;
        for (int i = 0; i < n; i++) {
            for (int c = 0; c <= amount; c++) {
                if (c < coins[i]) {
                    f[i + 1][c] = f[i][c];
                } else {
                    f[i + 1][c] = f[i][c] + f[i + 1][c - coins[i]];
                }
            }
        }
        return f[n][amount];
    }
}

4、最长公共子序列

1143. 最长公共子序列

java 复制代码
class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int m=text1.length(),n=text2.length();
        int[][] dp=new int[m+1][n+1];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(text1.charAt(i)==text2.charAt(j)){
                    dp[i+1][j+1]=dp[i][j]+1;
                }else{
                    dp[i+1][j+1]=Math.max(dp[i][j+1],dp[i+1][j]);
                }
            }
        }
        return dp[m][n];
    }
}

5、复原 IP 地址

93. 复原 IP 地址

java 复制代码
class Solution {
    List<String> res;
    List<String> path;
    String s;

    public List<String> restoreIpAddresses(String s) {
        res = new ArrayList<>();
        path = new ArrayList<>();
        this.s = s;
        dfs(0);
        return res;
    }

    public void dfs(int start) {
        if (start > s.length())
            return;
        if (start == s.length() && path.size() == 4) {
            StringBuilder temp = new StringBuilder();
            for (int i = 0; i < path.size(); i++) {
                temp.append(path.get(i));
                if (i != path.size() - 1)
                    temp.append(".");
            }
            res.add(temp.toString());
        }
        for (int i = start; i < s.length(); i++) {
            String temp = s.substring(start, i + 1);
            if (check(temp) >= 0 && path.size() < 4) {
                path.add(temp);
                dfs(i + 1);
                path.removeLast();
            }
        }
    }

    public int check(String ans) {
        if (ans.length() > 1 && ans.charAt(0) == '0')
            return -1;
        int sum = 0;
        for (int i = 0; i < ans.length(); i++) {
            sum = sum * 10 + ans.charAt(i) - '0';
        }
        if (sum > 255)
            return -1;
        return sum;
    }
}

6、删除排序链表中的重复元素 II

82. 删除排序链表中的重复元素 II

java 复制代码
/​**​
 * 删除链表中所有重复出现的元素,使每个元素只出现一次。
 * 例如,给定链表 1->2->3->3->4,返回 1->2->4。
 * 若链表为 1->1->1->2->3,返回 2->3。
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        // 创建虚拟头节点,简化删除头节点的逻辑
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        // pre 指针指向当前最后一个不重复的节点
        ListNode pre = dummy;

        // 外层循环:遍历链表,pre 总是指向已处理部分的末尾
        while (pre.next != null && pre.next.next != null) {
            int temp = pre.next.val; // 当前节点的值
            // 检查是否存在重复:当前节点的下一个节点与下下个节点值相同
            if (pre.next.next.val == temp) {
                // 内层循环:跳过所有值等于 temp 的节点
                while (pre.next != null && pre.next.val == temp) {
                    pre.next = pre.next.next; // 删除重复节点
                }
            } else {
                // 无重复时,pre 前移到下一个节点
                pre = pre.next;
            }
        }
        return dummy.next;
    }
}

7、寻找两个正序数组的中位数

4. 寻找两个正序数组的中位数

java 复制代码
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int tot = nums1.length + nums2.length; // 总元素个数
        // 判断总数是偶数还是奇数
        if (tot % 2 == 0) {
            // 偶数情况:取中间两个数的平均值
            int left = find(nums1, 0, nums2, 0, tot / 2);      // 第tot/2小的元素
            int right = find(nums1, 0, nums2, 0, tot / 2 + 1);// 第tot/2+1小的元素
            return (left + right) / 2.0;                      // 返回平均值
        } else {
            // 奇数情况:直接取中间数
            return find(nums1, 0, nums2, 0, tot / 2 + 1);
        }
    }

    // 辅助递归方法:在两个数组中寻找第k小的元素(k从1开始计数)
    int find(int[] n1, int i, int[] n2, int j, int k) {
        // 确保n1是较短的数组,优化递归效率
        if (n1.length - i > n2.length - j) 
            return find(n2, j, n1, i, k);
        
        // 边界情况1:n1已遍历完,直接返回n2的第k小元素
        if (i >= n1.length) 
            return n2[j + k - 1];
        
        // 边界情况2:k=1时,返回两数组当前起始位置的最小值
        if (k == 1) 
            return Math.min(n1[i], n2[j]);
        
        // 正常情况:二分查找法缩小范围
        // 计算两数组的中间位置(向下取整)
        int si = Math.min(i + (k / 2), n1.length);          // n1的参考切割点
        int sj = j + k - (k / 2);                         // n2的参考切割点
        
        // 比较两数组切割点前一个元素的值,排除较小部分
        if (n1[si - 1] > n2[sj - 1]) {
            // 排除n2的前(sj-j)个元素,继续在剩余部分找第(k - (sj-j))小的元素
            return find(n1, i, n2, sj, k - (sj - j));
        } else {
            // 排除n1的前(si-i)个元素,继续在剩余部分找第(k - (si-i))小的元素
            return find(n1, si, n2, j, k - (si - i));
        }
    }
}

8、二叉树的所有路径

257. 二叉树的所有路径

java 复制代码
class Solution {
    List<String> res;
    List<Integer> path;
    public List<String> binaryTreePaths(TreeNode root) {
        res=new ArrayList<>();
        path=new ArrayList<>();
        dfs(root);
        return res;
    }
    public void dfs(TreeNode root){
        if(root==null) return ;
        path.add(root.val);
        if(root.left==root.right){
            StringBuilder ans=new StringBuilder();
            for(int i=0;i<path.size();i++){
                ans.append(path.get(i).toString());
                if(i!=path.size()-1){
                    ans.append("->");
                }
            }
            res.add(ans.toString());
        }
        dfs(root.left);
        dfs(root.right);
        path.removeLast();
    }
}

二、语雀-场景题

1、秒杀场景下,怎么加库存?

✅秒杀场景下,怎么加库存?

2、5 分钟内最多允许用户尝试登录 3 次,如果错误次数超过限制,需要对该用户进行锁定。如何实现?

✅5 分钟内最多允许用户尝试登录 3 次,如果错误次数超过限制,需要对该用户进行锁定。如何实现?

3、两个不相关的网站A和B,如何实现A登录B也能自动登录

✅两个不相关的网站A和B,如何实现A登录B也能自动登录

1. 基于token

2. 基于Session

4、MQ出现消息乱序了如何解决?

✅MQ出现消息乱序了如何解决?

1. 顺序消息

2. 自己实现排序

5、MySQL千万级数据量,查询如何做优化?

✅MySQL千万级数据量,查询如何做优化?

1. 索引优化

2. 使用缓存

3. 数据归档

6、什么是数据归档,一般是怎么做的?

✅什么是数据归档,一般是怎么做的?

7、Redis、MySQL和MongoDB的区别是什么,各自适用场景呢?

✅Redis、MySQL和MongoDB的区别是什么,各自适用场景呢?

8、Redis实现分布式锁,加锁的时候,redis不可用了咋整?

✅Redis实现分布式锁,加锁的时候,redis不可用了咋整?

9、防止接口被恶意刷流量,除了限流还应在代码层面做哪些防护?

✅防止接口被恶意刷流量,除了限流还应在代码层面做哪些防护?

10、库存扣减、创建订单,如何拆成TCC?

✅库存扣减、创建订单,如何拆成TCC?

11、Redis保存库存的时候,如何避免被Redis清理掉?

✅Redis保存库存的时候,如何避免被Redis清理掉?

1. volatile

12、如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?

✅如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?

13、如何从 1TB 的搜索日志中找出搜索量最高的 10 个关键词

✅如何从 1TB 的搜索日志中找出搜索量最高的 10 个关键词?

14、用@Scheduled执行定时任务,如何避免集群的并发问题

✅用@Scheduled执行定时任务,如何避免集群的并发问题

15、下单支付过程,点击跳转支付,输入密码,支付完成后跳转到订单页,整个过程可能会有什么问题?架构方面做哪些设计?

✅下单支付过程,点击跳转支付,输入密码,支付完成后跳转到订单页,整个过程可能会有什么问题?架构方面做哪些设计?

1. 问题1:支付跳转失败

2. 问题2:支付状态未同步

3. 问题3:用户重复支付

4. 用户不支付,卡在支付中

16、有一张上百万条数据的单表,从前端页面、Java后台、数据库三个层面做查询优化

✅有一张上百万条数据的单表,从前端页面、Java后台、数据库三个层面做查询优化

1. 前端

2. Java代码

3. 数据库优化

17、假设还有很多内存,有什么情况还会频繁fullgc?

✅假设还有很多内存,有什么情况还会频繁fullgc?

18、5亿条数据放到布隆过滤器中,大概需要多大内存?如何估算?

✅5亿条数据放到布隆过滤器中,大概需要多大内存?如何估算?

相关推荐
LinXunFeng1 小时前
Flutter - GetX Helper 助你规范应用 tag
flutter·github·visual studio code
草梅友仁3 小时前
AI 图片文字翻译与视频字幕翻译工具推荐 | 2025 年第 23 周草梅周报
开源·github·aigc
qianmoQ7 小时前
GitHub 趋势日报 (2025年06月04日)
github
abcnull8 小时前
github中main与master,master无法合并到main
git·github
星哥说事9 小时前
使用VuePress2.X构建个人知识博客,并且用个人域名部署到GitHub Pages中
开源·github
勤劳打代码10 小时前
步步为营 —— Github Connection refused 分层诊断
github
寻月隐君11 小时前
深入解析 Rust 的面向对象编程:特性、实现与设计模式
后端·rust·github
qianmoQ1 天前
GitHub 趋势日报 (2025年05月31日)
github
油泼辣子多加1 天前
2025年06月06日Github流行趋势
github
粥里有勺糖1 天前
视野修炼-技术周刊第122期 | 发光图片制作
前端·javascript·github