算法学习打卡day47|单调栈系列题目

news2024/9/23 23:25:51

单调栈题目思路

  • 通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。时间复杂度为O(n)。
  • 单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。
单调栈解题步骤
  1. 建立一个栈,然后从头遍历元素。
  2. 既然为单调栈,那么肯定分为单调递增栈和单调递减栈(这里的单调递增或者递减指的是从栈顶到栈底方向),这里单调栈递增(从栈口到栈底顺序),就是求右边第一个比自己大的,单调栈递减的话,就是求右边第一个比自己小的。 那么分为两种情况:
    • 如果是单调递增栈时,当栈为空或者当前元素值小于栈顶元素时,执行push操作,此时的栈从栈顶到栈底为单调递增,而当前元素值大于栈顶元素值时,不符合单调递增,此时当前元素就是栈顶元素的右侧第一个比它大的元素,输出结果即可(注意这里要循判断栈顶元素是否都符合情况),当然左侧比自己大的元素就是当前栈顶的下一个元素了
    • 如果是单调递减栈时,同样的思路,当栈为空或者当前元素值大于栈顶元素时,执行push操作,此时的栈从栈顶到栈底为单调递减,而当前元素值小于栈顶元素值时,不符合单调递减,此时当前元素就是栈顶元素的右侧第一个比它小的元素,输出结果即可(注意这里要循判断栈顶元素是否都符合情况),当然左侧比自己小的元素就是当前栈顶的下一个元素了(接雨水和求柱子最大面积会用)
  • 注意:
    • 这里其实在元素等于栈顶元素的时候可以和另一个步骤合并,而不影响计算结果。
    • 单调栈解题,一般都是存数组下标,数组元素可以下标访问,很方便。

每日温度

力扣题目链接
题目描述:
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]
思路:

  • 从题目可以直接看到要求下一个更高温度在几天后,很显然就是求右边第一个比自己大的元素位置减去当前位置下标即位所求,直接使用单调栈来解题,很显然这道题时单调递增栈(从栈顶到栈底)。

代码实现:

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int> result(temperatures.size(), 0);
        stack<int> stk;
        for (int i = 0; i < temperatures.size(); ++i) {
            while (!stk.empty() && temperatures[i] > temperatures[stk.top()]) {
                int tmp = stk.top();
                result[tmp] = i - tmp;
                stk.pop();
            }
            stk.push(i);
        }
        return result;  
    }
};

下一个最大元素一

力扣题目链接
题目描述:
nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。

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

对于每个 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 。

思路:

  • 本题和每日温度类似,但是是在另一个数组里找,其实是一样的,我们可以用一个哈希map记录nums1的元素和下标映射关系,然后通过单调栈的方式去找nums2中每个元素的右侧最大值,当遇到符合条件的时候,就到map里找一下是否存在nums2里的这个元素,存在的话,就对应输出即可。

代码实现:

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int> result(nums1.size(), -1);
        unordered_map<int, int> map;
        for (int i = 0; i < nums1.size(); ++i) {
            map.insert(pair<int, int>{nums1[i], i});
        }
        stack<int> stk;
        for (int i = 0; i < nums2.size(); ++i) {
            //int num = nums2[i];
            while (!stk.empty() && nums2[i] > stk.top()) {
                if (map.count(stk.top())) {
                    result[map[stk.top()]] = nums2[i];
                }
                stk.pop();
            }
            stk.push(nums2[i]);
        }
        return result;
    }
};

下一个最大元素二

力扣题目链接
题目描述:
给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。

数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。

示例 1:
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。

示例 2:
输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]

思路:

  • 和上一个题类似,但是这次是循环数组,那么一般遇到循环数组的时候,我们没必要去把原数组拼接一次,直接让下标可以增长到2*n即可,在访问元素的时候对下标取余操作就不会越界。
  • 其他步骤就是单调栈的解题模板,注意这里可以剪枝一下,如果第一轮已经处理过的就不用再push一次了,没处理过的push即可。

代码实现:

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        stack<int> stk;
        vector<int> result(n, -1);
        for (int i = 0; i < 2 * n; ++i) {//上界为2n时,循环的时候模拟循环数组
            while (!stk.empty() && nums[i % n] > nums[stk.top()]) {
                result[stk.top()] = nums[i % n];
                stk.pop();
            }
            if (result[i % n] == -1) stk.push(i % n);//剪枝,之前已经处理过的可以不用push了。
        }
        return result;
    }
};

接雨水

力扣题目链接
题目描述:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
在这里插入图片描述

示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例 2:
输入:height = [4,2,0,3,2,5]
输出:9

提示:

n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105

思路:

  • 题目解读:若干个柱子,用凹槽去接雨水,这里是去求凹槽的面积之和,有两种思路:
    1. 按列计算(暴力解法),遍历每个元素,求出该元素能接的雨水高度,然后求和,这种情况需要分别求左右两侧比自己高的元素中的最大值,比如下图中的第6列,左侧比自己高的的最高柱子为第4列,右侧是第8列,那么第6列接雨水的高度就是第4列和第8列中高度较小的那个,这里是2
      在这里插入图片描述

    2. 按行计算(单调栈解法),找出两边第一个比自己高的柱子,然后求出宽度,高度是两边柱子中的最小值减去当前柱子高度,比如还是第6列,此时左右两侧第一个比自己高的是第5和第7列,那么此时宽度就是7 - 5 - 1 = 1,高度是两者的最小值减去第6列的高度:1 - 0 = 1,这里两侧的高度刚好相等了,而如果是第5列的话,那么左右两侧分别是第4和第8列,那么宽度为8 - 4 - 1 = 3,高度为两者的最小值减去第5列的高度:2 - 1 = 1,然后面积就是高度宽度相乘。
      在这里插入图片描述
      代码实现

  • 暴力解法(时间复杂度为 O ( n 2 ) O(n^2) O(n2),力扣无法通过):
class Solution {
public:
    int trap(vector<int>& height) {
        int sum = 0;
        int lhigh = 0, rhigh = 0;
        for (int i = 1; i < height.size() - 1; ++i) {
            //找左边比它大的
            lhigh = height[i], rhigh = height[i];
            for (int j = i - 1; j >= 0; --j) {
                if (height[j] >= lhigh) {//注意这里找的是左边最大的那个,所以一直和lhigh比较
                    lhigh = height[j];
                }
            }
            //找右边比它大的
            for (int k = i + 1; k < height.size(); ++k) {
                if (height[k] >= rhigh) {//注意这里找的是右边最大的那个,所以一直和rhigh比较
                    rhigh = height[k];
                }
            }
            sum += min(rhigh, lhigh) - height[i];
        }
        return sum;
    }
};
  • 暴力解法优化:其实在找左右两侧最大值的时候有很多重复比较,我们其实直接取前面一个元素的结果和当前值做比较即可((为什么和当前值比较?如果没有比自己大的,就用当前值,那么算的时候高度差为0,就没有高度无法接雨水了)),在遍历数组之前,先把左右两侧比自己高的最大值找出来。
class Solution {
public:
    int trap(vector<int>& height) {
        int sum = 0;
        vector<int> l_max_vec(height.size(), 0);
        vector<int> r_max_vec(height.size(), 0);
        //直接把每个位置的左侧最高柱子都计算出来
        l_max_vec[0] = height[0];
        for (int i = 1; i < height.size(); ++i) {
            l_max_vec[i] = max(l_max_vec[i - 1], height[i]);
        }
        //直接把每个位置的右侧最高柱子都计算出来
        r_max_vec[height.size() - 1] = height[height.size() - 1];
        for (int j = height.size() - 2; j >= 0; --j) {
            r_max_vec[j] = max(r_max_vec[j + 1], height[j]);
        }
        //循环一次,直接计算即可。
        for (int i = 1; i < height.size() - 1; ++i) {  
            sum += min(l_max_vec[i], r_max_vec[i]) - height[i];
        }
        return sum;
    }
};
  • 单调栈解法(按行求解):
class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> stk;
        int sum = 0;
        for (int i = 0; i < height.size(); ++i) {
            while (!stk.empty() && height[i] > height[stk.top()]) {
                int cur = stk.top();
                stk.pop();
                if (stk.empty())   break;
                int next = stk.top();//前面比它高的
                int high = min(height[i], height[next]) - height[cur];//高度差
                int weight = i - next - 1;//宽度
                sum += high * weight;//面积
            }
            stk.push(i);/*这里可以剪枝,如果相邻两个柱子高度相同算一个就行了,因为即使放进去,
                        high计算的时候也是0*/
        }
        return sum;
    }
};

柱状图中最大的矩形

力扣题目链接
题目描述:
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:
在这里插入图片描述

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2:
在这里插入图片描述

输入: heights = [2,4]
输出: 4

思路:

  • 和接雨水类似,但是本题更加复杂,接雨水是求凹槽,相当于是柱子外,本题是求柱子内的最大面积,**既然是求最大面积,那么本题需要找到的是每个柱子的左右两侧的第一个比自己小的那个柱子(注意这个题和前面四道题不一样了!!!,是求左右两侧比自己小的柱子,此时为栈顶到栈底单调递减),**这样的话用得到的宽度和当前柱子高度相乘即为已当前柱子为高度的矩形面积,然后依次对每个柱子求矩形面积取最大值即可。
  • 暴力解法:和接雨水不太一样,本题是找到左右两侧第一个比自己小的柱子(不再是找最小的柱子了(接雨水是找最大的柱子))
  • 注意:
    • 如果数组本身单调递增的话,那么入栈后整体呈现单调递减就找不到右侧比自己小的元素了,这种情况对于接雨水来说不用特殊处理(没有凹槽,雨水为0),但是本题不行,可以直接在原数组尾部加一个0,这样既不影响结果,也能找到了右侧比自己小的元素。
    • 对于数组单调递减的情况不用在数组开头添加元素,直接让left的高度设为-1即可。

代码实现

  • 单调栈解法:
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int result = 0;
        stack<int> stk;
        heights.push_back(0);//单独处理,尾部加0
        for (int i = 0; i < heights.size(); ++i) {
            while (!stk.empty() && heights[i] < heights[stk.top()]) {
                int top = stk.top();
                stk.pop();
                int left = -1;//单独处理,left设为-1
                if (!stk.empty())    left = stk.top();
                int weight = i - left - 1;
                int s = heights[top] * weight;
                result = max(result, s);
            }
            stk.push(i);
        }
        return result;
    }
};
  • 暴力解法:
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int result = INT_MIN;
        for (int i = 0; i < heights.size(); ++i) {
            int l_min = -1, r_min = heights.size();
            for (int j = i - 1; j >= 0; --j) {
                if (heights[j] < heights[i]) {
                    l_min = j;
                    break;
                }
            }
            for (int k = i + 1; k < heights.size(); ++k) {
                if (heights[k] < heights[i]) {
                    r_min = k;
                    break;
                }  
            }
            //cout << l_min << " " << r_min << endl;
            int weight = r_min - l_min - 1;
            int s = weight * heights[i];
            result = result > s ? result : s;
        }
        return result;
    }
};
  • 暴力解法优化:和接雨水优化类似,但是此处需要在for循环里用while循环去不断找到小于cur的柱子。(注意遇到等于的时候也要继续去找,当然也可以把等于逻辑拿出来单独写,其实是一样的)
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int result = INT_MIN;
        vector<int> l_min_vec(heights.size(), -1);//默认没有比当前柱子小的
        vector<int> r_min_vec(heights.size(), heights.size());//默认没有比当前柱子小的
        //求左侧第一个小于当前高度的柱子
        for (int i = 1; i < heights.size(); ++i) {
            int t = i - 1;
            while (t >= 0 && heights[t] >= heights[i]) {
                t = l_min_vec[t];
            }//大于一直往左走
            l_min_vec[i] = t;//直到遍历到头或者小于的时候
        }
        //求右侧第一个小于当前高度的柱子
        for (int j = heights.size() - 2; j >= 0; --j) {
            int t = j + 1;
            while (t < heights.size() && heights[t] >= heights[j]) {
                t = r_min_vec[t];
            }//大于等于一直往右走
            r_min_vec[j] = t;//直到遍历到头或者小于的时候
        }
        //求面积
        for (int i = 0; i < heights.size(); ++i) {
            int weight = r_min_vec[i] - l_min_vec[i] - 1;
            int s = weight * heights[i];
            result = max(s, result);
        }
        return result;
    }
};

总结

  • 单调栈题目大体模版都是一样的,就是while里的处理逻辑可能不同,可以先熟悉暴力解法,然后看看和单调栈解法的区别在哪,妙在哪里。

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

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

相关文章

大模型2024规模化场景涌现,加速云计算走出第二增长曲线

导读&#xff1a;2024&#xff0c;大模型第一批规模化应用场景已出现。 如果说“百模大战”是2023年国内AI产业的关键词&#xff0c;那么2024年我们将正式迈进“应用为王”的新阶段。 不少业内观点认为&#xff0c;2024年“百模大战”将逐渐收敛甚至洗牌&#xff0c;而大模型在…

DC-7靶机渗透详细流程

信息收集&#xff1a; 1.存活扫描&#xff1a; 由于靶机和kali都是nat的网卡&#xff0c;都在一个网段&#xff0c;我们用arp-scan会快一点&#xff1a; arp-scan arp-scan -I eth0 -l └─# arp-scan -I eth0 -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:dd:ee:6…

如何应对Android面试官->实战高级UI,用自定义View画一条锦鲤(上)

前言 如何用自定义View画一条鱼&#xff0c;其中涉及到哪些知识点&#xff1f;我们先上效果图&#xff1a; 涉及的知识点&#xff1a; 整体可以分为三大步骤 小鱼的绘制小鱼的摆动点击之后小鱼的游动 小鱼的绘制 想实现小鱼的绘制&#xff0c;我们首先需要分解下这个小鱼都由…

re:从0开始的CSS学习之路 5. 颜色单位

0. 写在前面 没想到在CSS里也要再次了解这些颜色单位&#xff0c;感觉回到了大二的数字图像处理&#xff0c;可惜现在已经大四了&#xff0c;感觉并没有学会什么AI的东西 1. 颜色单位 预定义颜色名&#xff1a;HTML和CSS规定了147种颜色名。例如&#xff1a;red yellow green …

如何使用websocket

如何使用websocket 之前看到过一个面试题&#xff1a;吃饭点餐的小程序里&#xff0c;同一桌的用户点餐菜单如何做到的实时同步&#xff1f; 答案就是&#xff1a;使用websocket使数据变动时服务端实时推送消息给其他用户。 最近在我们自己的项目中我也遇到了类似问题&#xf…

Django模板(二)

标签if 标签在渲染过程中提供使用逻辑的方法,比如:if和for 标签被 {% 和 %} 包围,如下所示: 由于在模板中,没有办法通过代码缩进判断代码块,所以控制标签都需要有结束的标签 if判断标签{% if %} {% endif %} : # athlete_list 不为空 {% if athlete_list %}# 输出 ath…

Qt 常用算法及正则表达式

目录 常用算法 正则表达式 常用算法 double c qAbs(a)&#xff0c;函数 qAbs() 返回 double 型数值 a 的绝对值 double max qMax(b,c)&#xff0c;函数 qMax() 返回两个数值中的最大值 int bnqRound(b)&#xff0c;返回一个与浮点数最接近的整数值(四舍五入) int cn q…

PyTorch深度学习实战(23)——从零开始实现SSD目标检测

PyTorch深度学习实战&#xff08;23&#xff09;——从零开始实现SSD目标检测 0. 前言1. SSD 目标检测模型1.1 SSD 网络架构1.2 利用不同网络层执行边界框和类别预测1.3 不同网络层中默认框的尺寸和宽高比1.4 数据准备1.5 模型训练 2. 实现 SSD 目标检测2.1 SSD300 架构2.2 Mul…

【Git版本控制 02】分支管理

目录 一、创建分支 二、切换分支 三、合并分支 四、删除分支 五、合并冲突 六、分支策略 七、bug分支 一、创建分支 # 当前仓库只有 master 一个主分支 # 可通过 git branch 是进行分支管理的命令&#xff0c;可通过不同参数对分支进行查看、创建、删除(base) [rootloc…

FXTM富拓监管变更!2024开年连续3家交易商注销牌照

交易商的监管信息是经常发生变更的&#xff0c;即使第一次投资时查询平台监管牌照&#xff0c;投资者仍需持续关注其监管动态。千万不要以为第一步审核好后就万事大吉了&#xff01; 2024年开年&#xff0c;就有3家交易商的重要信息发生变更&#xff0c;注销其金融监管牌照&…

Canvas的js库:Konva.js-像操作DOM一样,操作canvas

hello&#xff0c;我是贝格前端工场&#xff0c;最近在学习canvas&#xff0c;分享一些canvas的一些知识点笔记&#xff0c;本期分享Konva.js这个canvas框架&#xff0c;欢迎老铁们一同学习&#xff0c;欢迎关注&#xff0c;如有前端项目可以私信贝格。 Konva.js是一个强大的HT…

零基础学Python之整合MySQL

Python 标准数据库接口为 Python DB-API&#xff0c;Python DB-API为开发人员提供了数据库应用编程接口。 不同的数据库你需要下载不同的DB API模块&#xff0c;例如你需要访问Oracle数据库和Mysql数据&#xff0c;你需要下载Oracle和MySQL数据库模块。 DB-API 是一个规范. 它…

Spring Boot3整合Redis

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 1.导依赖 2.配置连接信息以及连接池参数 3.配置序列化方式 4.编写测试 前置条件 已经初始化好一个spr…

【daily updating】k3s kubeedge + opendFaas搭建教程 —— 欢迎交流

OpenFaas从入门到实战 – 踩坑指南 &#xff5c; k3dOpenFaas | deploy your first python function https://blog.alexellis.io/first-faas-python-function/ https://docs.openfaas.com/deployment/kubernetes/ 搭建环境&#xff1a;第一种方法失败&#xff0c;第二种方法…

1572.矩阵对角线元素的和(Java)

题目描述&#xff1a; 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 输入&#xff1a; mat [[1,2,3], [4,5,6], [7,8,9]] 输出&#xff1a; 25 解释&#xff1a;对角线的和为&…

cleanmymacX和腾讯柠檬哪个好用

很多小伙伴在使用Mac时&#xff0c;会遇到硬盘空间不足的情况。遇到这种情况&#xff0c;我们能做的就是清理掉一些不需要的软件或者一些占用磁盘空间较大的文件来腾出空间。我们可以借助一些专门的清理工具&#xff0c;本文中我们来推荐几款好用的Mac知名的清理软件。并且将Cl…

【Docker】Docker Image(镜像)

文章目录 一、Docker镜像是什么&#xff1f;二、镜像生活案例三、为什么需要镜像四、镜像命令详解docker rmidocker savedocker loaddocker historydocker image prune 五、镜像操作案例六、镜像综合实战实战一、离线迁移镜像实战二、镜像存储的压缩与共享 一、Docker镜像是什么…

上下固定中间自适应布局

实现上下固定中间自适应布局 1.通过position:absolute实现 定义如下结构 <body> <div class="container"> <div class="top"></div> <div class="center"></div> <div class="bottom"&…

2023年12月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A:10倍 B:2倍 C:4倍 D:8倍 答案:C 二进制进位规则是逢二进一,因此末尾添加一个0,是扩大2倍,添加两个0…

Redis篇之集群

一、主从复制 1.实现主从作用 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。主节点用来写的操作&#xff0c;从节点用来读操作&#xff0c;并且主节点发生写操作后&#xff0c;会把数据同…