周赛364(模拟+贪心,枚举,单调栈+前后缀分解,枚举+DFS)

news2025/1/11 19:48:59

文章目录

  • 周赛364
    • [8048. 最大二进制奇数](https://leetcode.cn/problems/maximum-odd-binary-number/)
      • 贪心 + 模拟
    • [100049. 美丽塔 I](https://leetcode.cn/problems/beautiful-towers-i/)
      • 枚举
    • [100048. 美丽塔 II](https://leetcode.cn/problems/beautiful-towers-ii/)
      • 单调栈 + 前后缀分解
      • [496. 下一个更大元素 I](https://leetcode.cn/problems/next-greater-element-i/)
    • [100047. 统计树中的合法路径数目](https://leetcode.cn/problems/count-valid-paths-in-a-tree/)
      • 枚举 + DFS

周赛364

8048. 最大二进制奇数

简单

给你一个 二进制 字符串 s ,其中至少包含一个 '1'

你必须按某种方式 重新排列 字符串中的位,使得到的二进制数字是可以由该组合生成的 最大二进制奇数

以字符串形式,表示并返回可以由给定组合生成的最大二进制奇数。

注意 返回的结果字符串 可以 含前导零。

示例 1:

输入:s = "010"
输出:"001"
解释:因为字符串 s 中仅有一个 '1' ,其必须出现在最后一位上。所以答案是 "001" 。

示例 2:

输入:s = "0101"
输出:"1001"
解释:其中一个 '1' 必须出现在最后一位上。而由剩下的数字可以生产的最大数字是 "100" 。所以答案是 "1001" 。

提示:

  • 1 <= s.length <= 100
  • s 仅由 '0''1' 组成
  • s 中至少包含一个 '1'

贪心 + 模拟

class Solution {
    public String maximumOddBinaryNumber(String s) {
        int cnt1 = 0, n = s.length();
        for(char c : s.toCharArray()){
            if(c == '1') cnt1 += 1;
        }
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < cnt1 - 1; i++){
            sb.append("1");
        }
        for(int i = 0; i < n - cnt1; i++){
            sb.append("0");
        }
        sb.append("1");
        return sb.toString();
    }   
}

100049. 美丽塔 I

中等

给你一个长度为 n 下标从 0 开始的整数数组 maxHeights

你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i ,高度为 heights[i]

如果以下条件满足,我们称这些塔是 美丽 的:

  1. 1 <= heights[i] <= maxHeights[i]
  2. heights 是一个 山状 数组。

如果存在下标 i 满足以下条件,那么我们称数组 heights 是一个 山状 数组:

  • 对于所有 0 < j <= i ,都有 heights[j - 1] <= heights[j]
  • 对于所有 i <= k < n - 1 ,都有 heights[k + 1] <= heights[k]

请你返回满足 美丽塔 要求的方案中,高度和的最大值

示例 1:

输入:maxHeights = [5,3,4,1,1]
输出:13
解释:和最大的美丽塔方案为 heights = [5,3,3,1,1] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]  
- heights 是个山状数组,峰值在 i = 0 处。
13 是所有美丽塔方案中的最大高度和。

示例 2:

输入:maxHeights = [6,5,3,9,2,7]
输出:22
解释: 和最大的美丽塔方案为 heights = [3,3,3,9,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山状数组,峰值在 i = 3 处。
22 是所有美丽塔方案中的最大高度和。

示例 3:

输入:maxHeights = [3,2,5,5,2,3]
输出:18
解释:和最大的美丽塔方案为 heights = [2,2,5,5,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山状数组,最大值在 i = 2 处。
注意,在这个方案中,i = 3 也是一个峰值。
18 是所有美丽塔方案中的最大高度和。

提示:

  • 1 <= n == maxHeights <= 103
  • 1 <= maxHeights[i] <= 109

枚举

class Solution {
    // 观察到数据范围10^3,可以枚举每个点作为山峰
    public long maximumSumOfHeights(List<Integer> maxHeights) {
        long ans = 0;
        int n = maxHeights.size();
        for(int i = 0 ; i < n; i++){
            long heightsum = maxHeights.get(i);
            for(int j = i-1, curtop = maxHeights.get(i); j >= 0; j--){
                curtop = Math.min(curtop, maxHeights.get(j));
                heightsum += curtop;
            }
            for(int j = i+1, curtop = maxHeights.get(i); j < n; j++){
                curtop = Math.min(curtop, maxHeights.get(j));
                heightsum += curtop;
            }
            ans = Math.max(ans, heightsum);
        }
        return ans;
    }
}

100048. 美丽塔 II

中等

给你一个长度为 n 下标从 0 开始的整数数组 maxHeights

你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i ,高度为 heights[i]

如果以下条件满足,我们称这些塔是 美丽 的:

  1. 1 <= heights[i] <= maxHeights[i]
  2. heights 是一个 山状 数组。

如果存在下标 i 满足以下条件,那么我们称数组 heights 是一个 山状 数组:

  • 对于所有 0 < j <= i ,都有 heights[j - 1] <= heights[j]
  • 对于所有 i <= k < n - 1 ,都有 heights[k + 1] <= heights[k]

请你返回满足 美丽塔 要求的方案中,高度和的最大值

示例 1:

输入:maxHeights = [5,3,4,1,1]
输出:13
解释:和最大的美丽塔方案为 heights = [5,3,3,1,1] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]  
- heights 是个山状数组,峰值在 i = 0 处。
13 是所有美丽塔方案中的最大高度和。

示例 2:

输入:maxHeights = [6,5,3,9,2,7]
输出:22
解释: 和最大的美丽塔方案为 heights = [3,3,3,9,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山状数组,峰值在 i = 3 处。
22 是所有美丽塔方案中的最大高度和。

示例 3:

输入:maxHeights = [3,2,5,5,2,3]
输出:18
解释:和最大的美丽塔方案为 heights = [2,2,5,5,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山状数组,最大值在 i = 2 处。
注意,在这个方案中,i = 3 也是一个峰值。
18 是所有美丽塔方案中的最大高度和。

提示:

  • 1 <= n == maxHeights <= 105
  • 1 <= maxHeights[i] <= 109

单调栈 + 前后缀分解

https://leetcode.cn/problems/beautiful-towers-ii/solutions/2456562/qian-hou-zhui-fen-jie-dan-diao-zhan-pyth-1exe/

class Solution {
    /** 
    10^5 次方数据,枚举每个点作为最大值会超时,怎么优化呢?
    
    计算从 a[0] 到 a[i] 形成山状数组的左侧递增段,元素和最大是多少,记到数组 pre[i] 中。
    计算从 a|i] 到 a[n-1] 形成山状数组的右侧递减段,元素和最大是多少,记到数组 suf[i] 中。
    答案就是 pre[i] + suf[i+1] 的最大值

    如何计算 pre 和 suf? 单调栈
    用单调栈,元素值从栈底到栈顶严格递增
    以 suf 为例,我们从右往左遍历 a,设当前得到的元素和为 sum
    1. 如果 a[i] 大于栈顶的元素值,那么直接把 a[i] 加到 sum 中,同时把i入栈 (栈中只需要保存下标)
    2. 否则,只要 a[i] 小于等于栈顶元素值,就不断循环,把之前加到sum 的撤销掉。
            循环结束后,从 a[i] 到 a[j-1] (假设现在栈顶下标是 j) 都必须是 a,
            把 a[i]*(j-1) 加到 sum 中
     */
    public long maximumSumOfHeights(List<Integer> maxHeights) {
        int[] a = maxHeights.stream().mapToInt(i -> i).toArray();
        int n = a.length;
        long[] suf = new long[n+1];
        Deque<Integer> st = new ArrayDeque<>();
        st.push(n); // 哨兵
        long sum = 0;
        // 计算suf
        for(int i = n-1; i >= 0; i--){
            int x = a[i];
            while(st.size() > 1 && x <= a[st.peek()]){
                int j = st.pop(); 
                // 撤销之前加到 sum 中的
                sum -= (long)a[j] * (st.peek() - j);
            }
            sum += (long) x * (st.peek() - i); // 从 i 到 st.peek()-1 都是 x
            suf[i] = sum;
            st.push(i);
        }
        long ans = sum;
        st.clear();
        st.push(-1); // 哨兵
        long pre = 0;
        for(int i = 0; i < n; i++){
            int x = a[i];
            while(st.size() > 1 && x <= a[st.peek()]){
                int j = st.pop();
                // 撤销之前加到 sum 中的
                pre -= (long) a[j] * (j - st.peek());
            }
            pre += (long) x * (i - st.peek());// 从 st.peek()+1 到 i 都是 x
            ans = Math.max(pre + suf[i+1], ans);
            st.push(i);
        }
        return ans;
    }
}

小羊肖恩

10^5 次方数据,枚举每个点作为最大值会超时,怎么优化呢?

我们考虑从中间点往前的结果的数组,可以发现其是这么更新的:

假设以 i-1 位置为中间点的结果数组前缀为 nums[i-1],那么 i 位置会**把其中大于上界的数改为上界,同时增加一个新的数。**而这个过程很类似于单调栈。

因为这个过程等价于,我们一旦结果的前缀中有更大的数,我们将其(整段)删掉,后面一整段区间换成新的数。

同时我们也可以对后缀进行相似的处理。得到前缀和后缀的结果后,我们将其加总即可得到每个点为中间点的答案,也就得到了这个问题的解


  1. “左边最近的更小值”是一个经典问题,可以用单调栈解决,详见 leetcode 496. 下一个更大元素 I。

  2. 改成去掉一些数变成先递增再递减,至少要去掉多少个数?

  • 这题是 1671. 得到山形数组的最少删除次数

496. 下一个更大元素 I

简单

nums1 中数字 x下一个更大元素 是指 xnums2 中对应位置 右侧第一个x 大的元素。

给你两个 没有重复元素 的数组 nums1nums2 ,下标从 0 开始计数,其中nums1nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j]下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1

返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素

示例 1:

输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。

示例 2:

输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。

提示:

  • 1 <= nums1.length <= nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 104
  • nums1nums2中所有整数 互不相同
  • nums1 中的所有整数同样出现在 nums2

**进阶:**你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗?

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map = new HashMap<>();
        // 维护一个单调递减栈
        Deque<Integer> dq = new ArrayDeque<>();
        for(int num : nums2){
            // 弹出比当前值小的元素,记录该弹出值的下一个更大元素
            while(!dq.isEmpty() && num > dq.peekLast()){
                map.put(dq.pollLast(), num);
            }
            dq.addLast(num);
        }
        int n = nums1.length;
        int[] res = new int[n];
        for(int i = 0; i < n; i++){
            res[i] = map.getOrDefault(nums1[i], -1);
        }
        return res;
    }
}

100047. 统计树中的合法路径数目

困难

给你一棵 n 个节点的无向树,节点编号为 1n 。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ui, vi] 表示节点 uivi 在树中有一条边。

请你返回树中的 合法路径数目

如果在节点 a 到节点 b 之间 恰好有一个 节点的编号是质数,那么我们称路径 (a, b)合法的

注意:

  • 路径 (a, b) 指的是一条从节点 a 开始到节点 b 结束的一个节点序列,序列中的节点 互不相同 ,且相邻节点之间在树上有一条边。
  • 路径 (a, b) 和路径 (b, a) 视为 同一条 路径,且只计入答案 一次

示例 1:

img

输入:n = 5, edges = [[1,2],[1,3],[2,4],[2,5]]
输出:4
解释:恰好有一个质数编号的节点路径有:
- (1, 2) 因为路径 1 到 2 只包含一个质数 2 。
- (1, 3) 因为路径 1 到 3 只包含一个质数 3 。
- (1, 4) 因为路径 1 到 4 只包含一个质数 2 。
- (2, 4) 因为路径 2 到 4 只包含一个质数 2 。
只有 4 条合法路径。

示例 2:

img

输入:n = 6, edges = [[1,2],[1,3],[2,4],[3,5],[3,6]]
输出:6
解释:恰好有一个质数编号的节点路径有:
- (1, 2) 因为路径 1 到 2 只包含一个质数 2 。
- (1, 3) 因为路径 1 到 3 只包含一个质数 3 。
- (1, 4) 因为路径 1 到 4 只包含一个质数 2 。
- (1, 6) 因为路径 1 到 6 只包含一个质数 3 。
- (2, 4) 因为路径 2 到 4 只包含一个质数 2 。
- (3, 6) 因为路径 3 到 6 只包含一个质数 3 。
只有 6 条合法路径。

提示:

  • 1 <= n <= 105
  • edges.length == n - 1
  • edges[i].length == 2
  • 1 <= ui, vi <= n
  • 输入保证 edges 形成一棵合法的树。

枚举 + DFS

0X3F:https://leetcode.cn/problems/count-valid-paths-in-a-tree/solutions/2456716/tu-jie-on-xian-xing-zuo-fa-pythonjavacgo-tjz2/

class Solution {
    private final static int MX = (int) 1e5;
    private final static boolean[] np = new boolean[MX + 1]; // 质数=false 非质数=true

    static {
        np[1] = true;
        for (int i = 2; i * i <= MX; i++) {
            if (!np[i]) {
                for (int j = i * i; j <= MX; j += i) {
                    np[j] = true;
                }
            }
        }
    }

    public long countPaths(int n, int[][] edges) {
        List<Integer>[] g = new ArrayList[n + 1];
        Arrays.setAll(g, e -> new ArrayList<>());
        for (var e : edges) {
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }

        long ans = 0;
        int[] size = new int[n + 1];
        var nodes = new ArrayList<Integer>();
        for (int x = 1; x <= n; x++) {
            if (np[x]) { // 跳过非质数
                continue;
            }
            int sum = 0;
            for (int y : g[x]) { // 质数 x 把这棵树分成了若干个连通块
                if (!np[y]) {
                    continue;
                }
                if (size[y] == 0) { // 尚未计算过
                    nodes.clear();
                    dfs(y, -1, g, nodes); // 遍历 y 所在连通块,在不经过质数的前提下,统计有多少个非质数
                    for (int z : nodes) {
                        size[z] = nodes.size();
                    }
                }
                // 这 size[y] 个非质数与之前遍历到的 sum 个非质数,两两之间的路径只包含质数 x
                ans += (long) size[y] * sum;
                sum += size[y];
            }
            ans += sum; // 从 x 出发的路径
        }
        return ans;
    }

    private void dfs(int x, int fa, List<Integer>[] g, List<Integer> nodes) {
        nodes.add(x);
        for (int y : g[x]) {
            if (y != fa && np[y]) {
                dfs(y, x, g, nodes);
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1037407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构与算法——16.二叉树

这篇文章我们来讲一下二叉树 目录 1.概述 2.代码实现 1.概述 树&#xff1a;&#xff08;Tree&#xff09;是计算机数据存储的一种结构&#xff0c;因为存储类型和现实生活中的树类似所以被称为树。 树的源头被称为根&#xff0c;树其余分叉点被称为节点&#xff0c;而树这…

未知非参数需求和有限价格变动的动态定价

英文题目&#xff1a;Dynamic Pricing with Unknown Non-Parametric Demand and Limited Price Changes 中文题目&#xff1a;未知非参数需求和有限价格变动的动态定价 单位&#xff1a;麻省理工学院&#xff0c;剑桥 时间&#xff1a;2019 论文链接&#xff1a;https://do…

制作频谱灯

最近研究了下傅里叶变换&#xff0c;用它可以通过采集声音信号由时域转换到频域内&#xff0c;从而得到声音的频谱信息&#xff0c;可以做个频谱灯。 主要使用ESP32来实现了他&#xff0c;实现效果如下&#xff1a; 频谱灯 为了可以带出去露营&#xff0c;我把它做的很大&…

ubuntu20.04下源码编译colmap

由于稠密重建需要CUDA&#xff0c;因此先安装CUDA&#xff0c;我使用的是3050GPU&#xff0c;nvidia-smi显示最高支持CUDA11.4。 不要用sudo apt安装&#xff0c;版本较低&#xff0c;30系显卡建议安装CUDA11.0以上&#xff0c;这里安装了11.1版本。 下载&#xff1a; cuda_1…

C语言之内存函数篇(3)

目录 memcpy memcpy的使用 memcpy的模拟实现 NO1. NO2. memcpy可否实现重叠空间的拷贝 my_memcpy memcpy memmove memmove memmove 分析 代码 memset memset的使用 memcmp memcmp的使用 <0 0 >0 今天我们继续介绍几个重要的内存操作函数。&…

js中的数据结构:栈,队列,链表,字典哈希表,树

栈&#xff1a;先进后出 队列&#xff1a;先进先出 链表&#xff1a; 单链表&#xff1a; 双链表&#xff1a; 环形链表&#xff1a;最后一个数据的next指针不是指向null&#xff0c;指向的是任意之间的一个数据&#xff0c;形成一个环 数组和链表的区别&#xff1a; 字典和哈…

FPGA的汽车尾灯控制Verilog

名称&#xff1a;汽车尾灯控制Verilog 软件&#xff1a;Quartus 语言&#xff1a;Verilog 要求&#xff1a; 设计一个汽车尾灯控制器。假设汽车尾部各有2个指示灯&#xff08;LED&#xff09;&#xff0c;分别代表转弯、刹车&#xff0c;控制器功能包括&#xff1a; &…

微信收款码费率0.38太坑了

作为一个有多年运营经验的商家&#xff0c;我本人在申请收款功能时曾经走过了不少弯路。我找遍了市面上的知名的支付公司&#xff0c;但了解到的收款手续费率通常都在0.6左右&#xff0c;最低也只能降到0.38。这个过程吃过不少苦头。毕竟&#xff0c;收款功能是我们商家的命脉&…

有什么好用的设备管理软件?智慧巡检对后勤运维有什么帮助?

定期巡检在设备管理、后勤管理和运维管理中扮演着不可或缺的角色&#xff0c;以及及时发现异常并控制风险。然而&#xff0c;传统巡检工作存在弊端。为了解决这些问题&#xff0c;“的修”报修系统对巡检管理功能进行了突破性的设计和开发。   “的修”报修巡检管理功能包含了…

C++之内部类实现总结(二百三十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

vscode终端中打不开conda虚拟包管理

今天&#xff0c;想着将之前鸽的Unet网络模型给实现一下&#xff0c;结果发现&#xff0c;在vscode中运行python脚本&#xff0c;显示没有这包&#xff0c;没有那包。但是在其他的ipynb中是有的&#xff0c;感觉很奇怪。我检查了一下python版本&#xff0c;发现不是我深度学习的…

转载 - 洞察问题本质,解决工作难题

作者&#xff1a;关苏哲 高效管理者的三大技能 问题界定的6个问题 1.你所需要解决的问题是什么&#xff1f; 2.你为什么需要解决这个问题&#xff1f; 3.你期待的理想结果是什么&#xff1f; 4.这个问题包括哪些子问题&#xff1f; 5.你曾经尝试过哪些解决方式&#xff1f…

Intel架构的基本知识

字节序 字节序根据存储的方向不同, 分为大端字节序(big-endian) 和 小端字节序(little-endian) 大端字节序(big-endian): 低字节存储在起始地址 小端字节序(little-endian): 高字节存储在起始地址 获得当前主机字节序 #include <iostream>using namespace std;int ma…

LabVIEW崩溃后所产生的错误日志文件的位置

LabVIEW崩溃后所产生的错误日志文件的位置 LabVIEW开发环境刚刚崩溃&#xff0c;请问我如何访问崩溃后自动生成的日志文件&#xff1f; LabVIEW崩溃后产生的转储文件位于何处&#xff1f; 代码导致了LabVIEW崩溃&#xff0c;请问哪些文件可以帮助NI技术支持了解具体原因&…

如何做到人声和背景音乐分离?简单粗暴,赶紧学起来~

在这个短视频盛行的时代&#xff0c;优质的背景音乐会让视频锦上添花&#xff0c;但也会造成类似的问题&#xff1a;想单独使用视频中的某一段人声&#xff0c;但会被背景音乐扰乱视听效果。这时就需要将人声和背景音乐进行分离了&#xff0c;今天就来教大家如何将人声和背景音…

最新文档:微信、企业号+地理位置定位+地图展示

概述 公司有需求&#xff0c;通过企业号打卡项目&#xff0c;需要用到企业微信定位 详细 前言 demo是基于微信、企业号平台的一个定位&#xff0c;地图展示项目 后台使用springboot架构搭建的与微信交互的服务&#xff0c;使用httpclient连接池&#xff0c;调用微信接口&…

小黑子—MyBatis:第二章

MyBatis入门2.0 四 小黑子诉说Mybatis核心配置文件详情4.1 多环境4.2 Mybatis的事务管理器 - transactionManager4.3 dataSource&#xff08;数据源&#xff09;4.3.1 不同类型下的数据源有不同的属性4.3.2 pool 和 unpooled 的区别4.3.3 配置具体的数据库连接池对象 4.4 prope…

【操作系统笔记三】内存寻址

物理寻址 主存&#xff08;内存&#xff09; 计算机主存也可以称为物理内存&#xff0c;内存可以看成由若干个连续字节大小的单元组成的数组每个字节都有一个唯一的物理地址&#xff08;Physical Address&#xff09;CPU访问内存前&#xff0c;先拿到内存地址&#xff0c;然后…

Django — 会话

目录 一、Cookie1、介绍2、作用3、工作原理4、结构5、用途6、设置7、获取 二、Session1、介绍2、作用3、工作原理3、类型4、用途5、设置6、获取7、清空信息 三、Cookie 和 Session 的区别1、存储位置2、安全性3、数据大小4、跨页面共享5、生命周期6、实现机制7、适用场景 四、P…

掌动智能浅析故障注入测试的好处与实践方法

在现代技术环境中&#xff0c;系统面临各种潜在的威胁和故障&#xff0c;如硬件故障、网络问题、软件错误等。为了应对这些挑战&#xff0c;开发团队需要确保系统在逆境中依然能够提供可靠的服务。故障注入测试是一种模拟现实故障和异常情况的方法&#xff0c;旨在提高系统的鲁…