滑动窗口算法——部分OJ题详解

目录

关于滑动窗口

部分OJ题详解

209.长度最小的子数组

3.无重复字符的最长字串

1004.最大连续1的个数Ⅲ

1658.将x减到0的最小操作数

904.水果成篮

438.找到字符串中所有字母异位词

30.串联所有单词的子串

76.最小覆盖子串


关于滑动窗口

其实滑动窗口也是通过双指针来实现,但是和双指针算法不同的是,滑动窗口的算法是两个指针同时移动,没有快慢之分,而通过对两个指针在数组中围出来的一个“区域”做操作,我们称为“滑动窗口算法”,我们通过下面8个OJ题来学习下:

什么是滑动窗口 

什么时候使用滑动窗口 

滑动窗口为什么能正确地解决这个问题  斯滑动窗口地时间复杂度 

滑动窗口如何用代码实现

部分OJ题详解

209.长度最小的子数组

209. 长度最小的子数组 - 力扣(LeetCode)

 解释下这道题:给一个整数数组nums,和一个数target,找出数组中满足和大于等于target的长度最小连续子数组,返回长度,没有返回0,通过示例能很简单理解,下面我们来分析下这道题:

  1. 首先是暴力解法,用两个for循环穷举所有的子数组,然后将数组的值依次相加,所以两个for循环,再加上求和的时候又一个循环,所以时间复杂度为O(N^3)
  2. 所以要优化暴力算法,使用“同向双指针”来优化,并且题目也说了,正整数数组,这代表加的数越多,值越大 --> 符合单调性的特征
  3. 假设数组为[2, 3, 1, 2, 4, 3],target=7。定义left指针指向2,right也指向2,定义一个sum=nums[right]记录两个指针中间所有值的和。刚开始sum=2,小于target,于是right++,一直小于7就一直right++,直到right指向第二个2时,sum=8,大于target,满足条件,记录当前长度len = right - left,然后left++继续判断。这个“同向双指针”就是我们说的“滑动窗口”
  4. 如何使用滑动窗口呢?步骤:①定义双指针left=0,right=0  ②进窗口  ③出窗口(23步重复)
  5. 以上面的第三点为例,第一步就是定义双指针,第二步就是判断滑动窗口内的和sum,如果sum小于7那么right++(进窗口,也就是扩大窗口右边界),如果sum大于等于7,先记录长度然后left++,sum-=nums[left-1](出窗口,也就是缩小窗口左边界),直到right到达数组结尾就退出循环
  6. 简单来说就是,sum小于target就进窗口right++,sum大于等于target就出窗口left++,所以整个滑动窗口提高效率就是利用单调性,规避了很多没有必要的枚举,最终整个过程就是left和right只把数组遍历了一遍,时间复杂度为O(2N) == O(N)
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0, right = 0, len = INT_MAX;
        int n = nums.size(), sum = 0;
        while(right < n)
        {
            sum += nums[right];
            while(sum >= target)
            {
                len = min(len, right - left + 1); //更新长度
                sum -= nums[left++];
            }
            right++;
        }
        if(len == INT_MAX) return 0;
        else return len;
    }
};

3.无重复字符的最长字串

3. 无重复字符的最长子串 - 力扣(LeetCode)

解释下这道题:给一个字符串,找出不含有重复字符的最长字串的长度,假设输入s="abcabcbb",因为无重复字符的最长字串是“abc”,所以返回3,s="bbbb",返回1;s="pwwkew",返回3,因为“wke”。下面我们来分析下这道题:

  1. 首先是暴力解法,以一个字符“a”为起点,依次往后枚举所有情况,遇到相同的字母“a”,记录长度,再固定b再次枚举,可以结合哈希表,判断字符是否重复出现,时间复杂度为O(N^2)
  2. 我们依然可以用滑动窗口优化暴力解法,假设字符串数组为[d, e, a, b, a, a, b, c, a],定义双指针,刚开始left和right都指向“d”,然后把d扔哈希表里面去,right++,每走一步,就把值扔哈希表里面去。当right走到第二个“a”时,判断哈希表时发现表中已经有“a”了,于是记录当前长度len = right - left + 1,然后left一直++,直到left跳过第一个“a”的位置,然后right++再判断,重复上面的操作
  3. 所以步骤大致为三步:①left = 0, right = 0  ②进窗口,把right指向的字符串扔哈希表里去,right++  ③当把right扔哈希表里时发现是重复字符,记录长度,然后出窗口,left++一直到第一个重复字符后面,更新结果,然后循环再次right++重复步骤② 
class Solution 
{
public:
    int lengthOfLongestSubstring(string s) 
    {
        int hash[128] = {0}; //用数组来模拟哈希表,数字为0就未出现,为1就是出现了一次,为2就是出现了两次
        int left = 0, right = 0, n = s.size(), ret = 0;
        for(; right < n; right++)
        {
            //进窗口,把字符扔哈希表里去
            hash[s[right]]++;
            while(hash[s[right]] > 1) //判断在数组中该字符是否出现两次,如果是就出窗口,让left位置的字符离开哈希表,left再右移
            {
                hash[s[left]]--; //left一直往后减,直到减去重复字符的第一个
                left++;
            }
            ret = max(ret, right - left + 1); //更新最后结果
        }
        return ret;
    }
};

1004.最大连续1的个数Ⅲ

1004. 最大连续1的个数 III - 力扣(LeetCode)

解释下这道题:给一个数组,其只有“1”和“0”两种数,再给一个数K,表示在这个数组中最多可以把K个0变成1,请判断最长的连续1的最大个数。下面来分析下这道题:

  1. 这道题用正常的思路来看,找出最长的连续的1的个数,其实很难很难,所以我们可以换个角度思考:我们其实只需要找出一个区域,使得这个区域的0的个数不超过K个就可以了,所以这道题可以转化为:找出0的个数不超过K个的最长子数组长度
  2. 首先是暴力解法 + zero计数器:定义两个指针,一个起点一个终点,依次枚举起点到终点的子数组,当zero技术大于K时,记录当前子数组长度,然后left++,right+left+1 继续检测
  3. 暴力解法肯定会超时,所以我们可以用滑动窗口来优化暴力解法。暴力解法是left++后,再次枚举,但是其实可以不必再枚举,可以让left一直++,直到left经过第一个0后才停下来,然后再right=left+1
  4. 步骤还是三步:①定义双指针left = 0,right = 0  ②进窗口:当right为1时不管,当right为0时,计数器++  ③出窗口:当计数器大于K时,先记录长度,left一直右移,每次移动判断是否为0,当为0时,跳过后停止,计数器--
class Solution {
public:
    int longestOnes(vector<int>& nums, int k) {
        int left = 0, right = 0, ret = 0, n = nums.size();
        int zeroNum = 0; //0计数器
        while(right < n)
        {
            if(nums[right] == 0) zeroNum++;
            while(zeroNum > k) //判断
            {
                if(nums[left] == 0)
                {
                    zeroNum--;
                }
                left++;
            }
            ret = max(ret, right - left + 1); //更新结果
            right++;
        }
        return ret;
    }
};

1658.将x减到0的最小操作数

1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)

解释下这个题目:给一个整数数组nums和一个整数x,每次操作时只能从数组两端进行操作,使得最左边或最右边的值相加后是否等于x,可以使用多个数,如果恰好等于x则返回使用数的个数,如果不能返回-1,并且每次使用完一个数后要在原数组上把该数删掉,下面我们来分析下这道题:

  1. 这道题和上面的求“最大连续1的个数”一样,正面看很难,但是所谓“正难则反”,我们也可以从另一个角度来看这题:我们可以把左边的区间的数计算和为a,右边区间计算和为b,要使得a+b=x,但是我们可以反过来,只要保证中间区域的连续区间的和c=sum-x即可(sum为为该数组所有元素的和),要求的是两边最小的区间,那么反过来就是求最大中间区间长度
  2. 所以这道题可以转化为:求最长的连续区间,使得区间的和正好等于sum-x
  3. 首先是暴力解法:先定义双指针left=0,right=0,计算target=sum-x,ret += nums[right++],当ret == target时,记录长度然后left++,right = left+1重置双指针后继续遍历计算
  4. 暴力解法肯定是超时,所以我们可以用滑动窗口来优化:当ret == target时,right不要动,left一直++并且ret-=nums[left],每次都做判断,当ret小于target时,right++然后再判断,当ret == target时就计算返回值
  5. 所以步骤也是三个:①定义双指针  ②进窗口,sum += nums[right]  ③出窗口,判断如果sum>target时,一直出窗口,也就是一直sum -= nums[left++],直到sum小于target才回归步骤②;如果sum = target,记录长度然后尝试返回
class Solution {
public:
    int minOperations(vector<int>& nums, int x)
    {
        int left = 0, right = 0, sum = 0, n = nums.size();
        int ret = 0; //计算滑动窗口中间的和
        for(auto e : nums) sum += e; //计算数组总和
        int target = sum - x; //计算判断值
        if(target < 0) return -1;
        
        int a = -1; //要返回的值
        while(right < n)
        {
            ret += nums[right]; //先雷打不动,进窗口
            while(ret > target) //滑动窗口的值大于判断值时,出窗口
            {
                ret -= nums[left];
                left++;
            }
            if(ret == target) 
            {
                a = max(a, right - left + 1);
            }
            right++;
        }
        return a == -1 ? -1 : n - a; 
    }
};

904.水果成篮

904. 水果成篮 - 力扣(LeetCode)

原题比较长,简单解释下: 就是在一个数组中找一个连续的子数组,使该子数组只能有一种或两种数组,返回可以找到的最长的子数组的长度,下面我们拉分析下这道题:

  1. 暴力解法还是暴力枚举 + 哈希表,穷举所有符合条件的子数组然后找到最长的,返回最长的长度
  2. 接着我们用滑动窗口来优化,先定义双指针left = right = 0,然后进窗口,把right的值扔哈希表里去使该数的数量++,然后是出窗口,先判断扔进去哈希表里的数的种类是否大于2,如果大于2,先把该数在哈希表里的数量--,然后left++,当哈希表里的两个数有一个为0时,left停止++,更新结果
class Solution {
public:
    int totalFruit(vector<int>& f) 
    {
        int left = 0, right = 0, n = f.size(), ret = 0;
        int kind = 0; //统计窗口内水果种类
        int hash[100001] = {0}; //依旧用数组来代替哈希表
        while(right < n)
        {
            if(hash[f[right]] == 0) kind++; 
            hash[f[right]]++;
            while(kind > 2) //当种类大于2时,一直出窗口,使kind恢复成2
            {
                hash[f[left]]--; 
                if(hash[f[left]] == 0) kind--; //当哈希表该位置水果数量为0时,
                left++;
            }
            ret = max(ret, right - left + 1);
            right++;
        }
        return ret;
    }
};

438.找到字符串中所有字母异位词

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

这道题标着中等,其实已经有了困难的难度了,下面解释下题目: 给两个字符串s和p,找到s种所有p的异位词,返回这些字串的起始索引,不考虑输出顺序(异位词:指由相同字母重新排列组合形成的字符串)

①假设s="cbaebabacd"  p="abc"  输出[0, 6]  因为起始索引0的字串是"cba",是"abc"的异位词;而且起始索引6的字串是"bac",也是"abc"的异位词
②s="abab"  p="ab"  输出[0, 1, 2]  因为起始索引012的字串分别位"ab""ba""ab",都是"ab"的异位词
 

下面我们来分析下这道题:

  1.  先处理一个小问题:如何快速判断两个字符串是否是异位词?我们可以先把两个字符串用双指针排序,但是时间复杂度为O(NlogN + N),太耗时;所以由于我们不关心是顺序,只关心字符个数是否就绪,所以我们依旧可以用哈希表来搞,把p字符串全扔哈希表里去,然后s字符串也扔哈希表,只要判断两个哈希表里的字符个数是否一样就可以了
  2. 暴力解法:把p的字符扔hash1,长度为m,然后我们在s穷举所有长度为m的字串,把字串扔哈希表里去,每扔完一个字串就比较下两个哈希表的内容是否相同即可,比较完后清空hash2
  3. 优化暴力解法:当有列举子数组或者列举字串时,肯定要想到滑动窗口。假设s字符串为“c b a e b a b a c d”,p为“a b c”。当用暴力枚举时,我们先只枚举开始的两个字串“c b a”与“b a e”,比较下两个字串,可以发现除了字符“c”  “e”,中间的“b a”是一样的,已经在哈希表中存在,所以只需要把第一个字符从哈希表中删除,把下一个字符添加进哈希表就完成了下一次枚举
  4. 因此第二次枚举时,没有必要重新从第二个位置添加三个字符到哈希表,下一次枚举也是,把第一个字母添加进哈希表,把下一个字母扔进去,就可以用滑动窗口来解决这个问题
  5. 以s字符串为“c c b a e b a b a c d”,p为“a b c”为例。刚开始left和right都指向第一个c,然后先把p的三个字符放到hash1里去,并且数量都为1,然后把c扔进hash2,那么c的个数变为1,然后与hash1的c的数量做对比,此时1<=1所以为”有效字符“,count++。当right++后,c的数量变为了2,2>1,不符合有效字符,count不变,right继续++
  6. right指向b时,符合条件,count再++,right指向a,count再++。这时窗口长度为4了,left++,这时候如果left-1的字符的数量>1,那么表示该left-1的字符“c”是多余字符,删掉;hash2的c的数量变为1,然后该窗口已经符合要求,记录left的值,count不更新,然后right再++指向e,由于hash1没有e,此时count不做处理,此时窗口长度为4了,left++,但是left-1为有效字符,hash2中c的数量变为0,count--
  7. 所以大致步骤就是:①进窗口:进入后,hash2[in] <= hash1[in],如果符合条件,count++,不符合count不变    ②判断是否出窗口:出去前,hash2[out] <= hash1[out],如果符合条件,count--,不符合count不变    ③更新结果:如果count == m,输出left
class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int hash1[26] = { 0 }; //存储p字符串中字符的数量
        int hash2[26] = { 0 }; //存储s字符串中字符的数量
        for(auto e : p) hash1[e - 'a']++; //把p先扔hash1里去用于判断异位词
        int len = p.size(); //定义滑动窗口大小,也就是字符串p的长度
        
        vector<int> v; //存储符合条件的索引值,用于返回
        int left = 0, right = 0, n = s.size();
        int count = 0; //表示有效字符个数
        while(right < n)
        {
            char in = s[right]; //in表示该次循环中滑动窗口最后一次进入窗口的字符
            hash2[in - 'a']++; //把in字符扔哈希表里,也就是让对应字符的位置数量++
            if(hash2[in - 'a'] <= hash1[in - 'a']) count++; //如果滑动窗口中的该字母与p中的某个字母一样,那么表示有效字符+1
            if(right - left + 1 > len) //判断窗口长度是否等于len,如果窗口大于len了,那么出窗口,left++并移除哈希表中该字母,维护count
            {
                char out = s[left++]; //表示出窗口的字母,也就是滑动窗口的前面一个字母
                if(hash2[out - 'a'] <= hash1[out - 'a']) count--; //表示如果出窗口的字母与p字符串中字母种类相同且数量小于p中的,那么表示该字符为有效字符,移除有效字符,count--
                hash2[out - 'a']--; //移除hash2中该元素,就是将该元素的在哈希表中的数量--
            }
            if(count == len) v.push_back(left); //有效字符个数符合p的长度,表示滑动窗口中字符的种类和数量与p字符串,符合异位词条件
            right++;
        }
        return v;
    }
};

30.串联所有单词的子串

30. 串联所有单词的子串 - 力扣(LeetCode)

这道题和上面那一道很相似,下面来解释下这道题:给一个字符串s和一个字符串数组words,words中所有字符串的长度相同。假设s="barfoothrfoobarman"  words={"foo", "bar"}  返回[0, 9]  因为0开始的字符串是barfoo,从9开始的字符串是foobar,是words中所有字符串以任意顺序排列连接起来的字串,如果没有结果则返回空数组,,下面来分析下这道题:

  1. 就上面的为例,words中每个字符串的长度为3,那么我们可以对s字符串进行处理,我们把s字符串每三个字符进行划分,每三个字符看成一个字符,那么就和上一道题的“找出所有字母的异位词”的那个题目一样了。但是由于该题有顺序要求,所有不能一股脑全扔哈希表里去,得采取一些策略
  2. 这道题与上个题目不一样的地方:①哈希表不能再用数组了,要用真的哈希表,可以用unordered_map<string, int> 来定义hash1和hash2    ②left和right每次移动时,不再只++一次了,而应该 += 单词的长度len    ③滑动窗口的执行次数也是len次,除此之外其余操作和上题一样
class Solution 
{
public:
    vector<int> findSubstring(string s, vector<string>& words) 
    {
        vector<int> v;
        unordered_map<string, int> hash1; //保存words内所有单词的频次
        for(auto& s : words) hash1[s]++;
        int len = words[0].size(); //每个单词的长度
        int n = words.size(); //字符串数组中字符串的数目
        for(int i = 0; i < len; i++) //执行len次滑动窗口的次数
        {                                    
            unordered_map<string ,int> hash2; //保存窗口内所有单词的频次
            for(int left = i, right = i, count = 0; right + len <= s.size(); right += len) /* 移到最后时,把最后一个长度为len的单词也加进去后,不能再往后移动了 */
            {   
                //进窗口 + 维护count
                string in = s.substr(right, len); //in是即将进入窗口的字符串
                hash2[in]++;
                if(hash1.count(in) && hash2[in] <= hash1[in]) count++; //如果加进hash2后该单词的频次小于hash1的,那么该单词就是有效字符
                //判断,当窗口大小大于字符串总长度,就要出窗口 + 维护count
                if(right - left + len > len * n)
                {
                    string out = s.substr(left, len);
                    if(hash1.count(out) && hash2[out] <= hash1[out]) count--; //如果hash2里该单词的频次小于hash1里的,那么要出窗口的单词是有效字符,count要--
                    hash2[out]--;
                    left += len;
                }
                //更新结果
                if(count == n) v.push_back(left);
            }
        }
        return v;
    }
};

76.最小覆盖子串

76. 最小覆盖子串 - 力扣(LeetCode)

该题标着困难难度,但其实难度远没有上面两题高,这题最多算中等难度,下面来解释下题目:给给一个字符串s,一个字符串t,返回s中覆盖t所有字符的最小字串,如果不存在就返回空串。

注意:t中重复字符,我们寻找的子字符串中该字符数量必须不少于t中该字符的数量,如果s中存在这样的子串,我们保证它是唯一的答案

s="ADOBECODEBANC" t="ABC"  输出"BANC,因为ADOBEC包含ABC,后面的BANC也包含,但是后面的字串比前面短,所以返回后面那个BANC
 

下面来分析下这道题:

  1. 首先还是暴力算法,还是暴力枚举出所有的连续字串,然后两个哈希表比较即可
  2. 现在对暴力算法进行优化:还是left和right,当两个指针的区域符合要求时,left,然后right=left+1重新遍历,这是暴力算法,但是其实right没必要先回去,先分析下要不要回去,left++后有两种结果:①left++后,区域仍符合要求,那么right可以不动,left继续++然后再次判断    ②当left++后不符合要求,right也可以不回去,right就一直往后走直到符合要求,这个操作前面已经见过很多了,就是利用了单调性
  3. 前面也说过,只要看到是列举子字符串或子数组等子的,都可以考虑用滑动窗口,然后只要是涉及到“覆盖”,“查找相同”类似的,都可以用哈希表来搞,所以下面就是用“滑动窗口” + “哈希表”来解决这道题
  4. 滑动窗口的步骤绝大多数清空下都是那三个:①定义双指针:left = 0, right = 0    ②进窗口:把right扔哈希表里去,然后和上面几道题一样维护有效字符计数count,也就是当hash2(in) 时如果符合条件,那么count++    ③然后还是判断 + 出窗口:如果hash2中的t字符数量都 >= hash1的字符时,就出窗口,left++,然后if(hash2(out) == hash1(out) ) count--,最后如果count符合要求count == hash1.size(),那么就更新结果
class Solution 
{
public:
    string minWindow(string s, string t) 
    {
        int hash1[128] = { 0 }; //统计t字符串中每一个字符的频次
        int hash2[128] = { 0 }; //统计窗口内每一个字符的频次
        int kinds = 0; //统计有效字符有多少种
        for(auto ch : t)  if(hash1[ch]++ == 0) kinds++; //统计有效字符种类时顺便把字符扔哈希表里去

        int minlen = INT_MAX, begin = -1;
        for(int left = 0, right = 0, count = 0; right < s.size(); right++)
        {
            char in = s[right];
            if(++hash2[in] == hash1[in]) count++;
            while(count == kinds) //判断
            {
                if(right - left + 1 < minlen) //当有比原来字符串长度更短的字符串时,更新结果
                {
                    minlen = right - left + 1;
                    begin = left;
                }
                char out = s[left++];
                if(hash2[out]-- == hash1[out]) count--;
            }
        }
        if(begin == -1) return "";
        else return s.substr(begin, minlen);
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

气膜移动宴会厅:现代化宴会解决方案—轻空间

随着社会经济的发展和人们生活水平的提高&#xff0c;各类宴会、庆典和活动的需求日益增加。然而&#xff0c;传统的宴会厅受限于固定的地点和昂贵的建设成本&#xff0c;无法灵活应对不同规模和地点的需求。在此背景下&#xff0c;气膜移动宴会厅作为一种创新的解决方案&#…

北京小程序开发如何选择开发团队与开发语言?

随着移动互联网的飞速发展&#xff0c;小程序的开发与使用也变得越来越频繁。对于商户来说&#xff0c;市面上的小程序开发团队数量众多又鱼龙混杂&#xff0c;应该如何选择合适的开发团队与开发语言呢&#xff1f; 一&#xff0e; 北京小程序的开发语言的种类及不同 北京小程…

吉时利 Keithley2461 数字源表

Keithley2461吉时利SMU高电流数字源表 2461 型图形化高电流数字 SourceMeter SMU 2461 高电流 SMU 凭借其 10A/1000W 脉冲电流和 7A/100W 直流电流能力以及双 18 位 1MS/s 数字转换器&#xff0c;优化用于检定和测试高功率材料、器件和模块&#xff0c;例如碳化硅 (SiC)、氮化…

修改 app id - 鸿蒙 HarmonyOS Next

修改项目 app id 后通过真机 build run 的时候抛出了如下异常; 项目中更改后的配置与真机的不匹配; {app: {bundleName: "com.xxxxxx.xxx_harmony",vendor: "xxxxxx",versionCode: 1,versionName: "3.5.00",icon: "$media:app_icon",…

期末C语言易错知识点整理

1.在定义多维数组时&#xff0c;除了最左边的维度&#xff0c;其余的维度必须明确指定大小 2.int m[1][4]{4}; 定义的是一个 1 行 4 列的二维数组&#xff0c;初始化时提供了一个元素 4&#xff0c;其余元素默认初始化为 0&#xff0c;因此是正确的。 3.二维数组 a[3][6] 中的索…

IDEA中配置log4j日志

由于开发过程中总是会出现一些当时觉得莫名其妙的问题&#xff0c;排查问题时很难定位到具体的位置&#xff0c;所以这个时候如果加入日志可以在控制台打印出日志记录&#xff0c;遍能很快定位到问题的位置&#xff1b; 1.添加依赖 <dependency><groupId>log4j<…

goLang小案例-打印99乘法表

goLang小案例-打印99乘法表 1. 打印99乘法表 func Print99multiplication1() {//横向9排for i : 1; i < 9; i {//竖向9列//第一批第一个 和第一列比较 如果大于排就结束//假设第三排i3 最走有三列 1*3 2*3 3*3//j3打印完 j 当j4就要结束 以此类推for j : 1; j < i; j …

Meet AI4S 直播预告丨房价分析新思路:神经网络直击复杂地理环境中的空间异质性

近年来&#xff0c;房地产市场起起落落&#xff0c;房价已经成为了扰动居民幸福感的重要影响因素。大多数家庭都需要面对「买不买房、何时买房、在哪儿买房、买什么房」的艰难抉择&#xff0c;每一个问题的答案都在某种程度上与房价的波动息息相关。 近年来&#xff0c;我国各…

v-for中key的原理以及用法

在 Vue.js 中&#xff0c;v-for 指令用于基于源数据多次渲染元素或模板块。当使用 v-for 渲染列表时&#xff0c;为每个列表项提供一个唯一的 key 属性是非常重要的。key 的主要作用是帮助 Vue 跟踪每个节点的身份&#xff0c;从而重用和重新排序现有元素。 先来张原理图&#…

go sync包(五) WaitGroup

WaitGroup sync.WaitGroup 可以等待一组 Goroutine 的返回&#xff0c;一个比较常见的使用场景是批量发出 RPC 或者 HTTP 请求&#xff1a; requests : []*Request{...} wg : &sync.WaitGroup{} wg.Add(len(requests))for _, request : range requests {go func(r *Reque…

IBM Spectrum LSF RTM,针对 IBM Spectrum LSF 环境的高级报告、跟踪和监控工具

亮点 为 IBM Spectrum LSF 环境提供性能监控和报告 监控 FlexNet Publisher 和 Reprisebased 许可证的使用&#xff0c;提供详细和总结性报告 通过多个级别&#xff08;包括应用程序和组织&#xff09;的报告来监控共享存储的利用率 提供强大的生产力工具&#xff0c;包括操…

计算机公共课面试常见问题:线性代数篇

目录 1. 特征向量和特征值代表什么含义&#xff1f; 2. 矩阵的秩是什么&#xff1f;满秩代表什么&#xff1f;不满秩呢&#xff1f; 3. 奇异值分解是什么&#xff1f; …

二手房和新房市场冰火两重天!原因为何?杭州给出了答案

随着房市的回暖&#xff0c;也出现了不少的不利的消息&#xff0c;一边二手房被抢购&#xff0c;一边是新房难卖&#xff0c;为何如此矛盾&#xff1f;近期杭州的楼市行情给出了答案。 5月份在诸多政策的刺激下&#xff0c;杭州楼市保持了热度&#xff0c;不过却有点凉风&#…

“论云上自动化运维及其应用”写作框架,软考高级,系统架构设计师

论文真题 云上自动化运维是传统IT运维和DevOps的延伸&#xff0c;通过云原生架构实现运维的再进化。云上自动化运维可以有效帮助企业降低IT运维成本&#xff0c;提升系统的灵活度&#xff0c;以及系统的交付速度&#xff0c;增强系统的可靠性&#xff0c;构建更加安全、可信、…

【SGX系列教程】(三)Intel-SGX 官方示例分析(SampleCode)——Cxx11SGXDemo

文章目录 示例一. Cxx11SGXDemo1.1 README1.2 重点代码分析1.2.1 App/App.cpp1.2.2 App/TrustedLibrary/Libcxx.cpp1.2.3 Enclave.edl1.2.4 Enclave/TrustedLibrary/Libcxx.cpp1.2.5 Enclave/Enclave.cppEnclave.h 1.3 编译执行1.4 总结 示例二. Cxx14SGXDemo示例三. Cxx17SGXD…

SpringBoot集成道历(实现道历日期查询)

官网地址&#xff1a;官网地址https://6tail.cn/calendar/api.html 1、导入依赖 <dependency><groupId>cn.6tail</groupId><artifactId>lunar</artifactId><version>1.3.9</version></dependency><dependency><group…

斜光测距的原理及python实现

1.前言 最近做了一个基于opencv的斜光测距的小项目&#xff0c;东西不多&#xff0c;但是很有意思&#xff0c;值得拿出来学一学。项目里面需要比较精确的定位功能&#xff0c;将前人matlab代码移植到python上&#xff0c;并且做了一些优化&#xff0c;简化逻辑(毕竟我是专业的…

uView 2.0:uni-app生态的利剑出鞘,引领UI框架新纪元

引言 随着移动互联网的快速发展&#xff0c;跨平台应用开发成为了开发者们关注的焦点。uni-app&#xff0c;一个基于Vue.js的跨平台应用开发框架&#xff0c;因其高效、易用的特性而广受欢迎。在uni-app的生态系统中&#xff0c;UI框架的选择对于开发者而言至关重要。今天&…

AI 编程探索- iOS动态标签控件

需求分析&#xff1a; 标签根据文字长度&#xff0c;自适应标签居中显示扩展 超过内容显示范围&#xff0c;需要换行显示&#xff0c;且保持居中显示 AI实现过程 提问&#xff1a; 回答&#xff1a; import UIKit import SnapKitclass DynamicLabelsContainerView: UIView…

docker 多网卡指定网卡出网

前言 宿主机中有多个网卡 ens160 192.168.4.23/20 内网通信用 ens192 10.31.116.128/24 出公网访问-1 ens193 10.31.116.128/24 出公网访问-2 现在需要不同容器中不同出网访问&#xff0c;举例 容器1 192.168.0.1/20 网段走宿主机 ens160网卡&#xff0c;否则全部走ens192 网…