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

news2024/9/18 17:07:51

目录

关于滑动窗口

部分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.coloradmin.cn/o/1872974.html

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

相关文章

侯捷C++面向对象高级开发(上)-1-头文件与类的声明

1.数据和函数比较 2.代码基本形式 3.c vs c输出 4.头文件防卫式声明 5.头文件布局 6.class模板简介

口碑最好的麦克风品牌有哪些?轻揭无线领夹麦克风哪个牌子好!

​无线领夹麦克风&#xff0c;无疑是现代音频技术的杰出代表。它摆脱了传统有线麦克风的束缚&#xff0c;让声音的传播更加自由、灵活。无论是追求极致音质的音乐爱好者&#xff0c;还是需要高效沟通的商务人士&#xff0c;无线领夹麦克风都能满足你的需求&#xff0c;让你的声…

MySQL实训项目——餐饮点餐系统

项目简介&#xff1a;餐饮点餐系统是一款为餐厅和顾客提供便捷点餐服务的在线平台。通过该系统&#xff0c;餐厅能够展示其菜单&#xff0c;顾客可以浏览菜品&#xff0c;并将其加入购物车或直接下单。系统还提供了订单管理功能&#xff0c;方便餐厅跟踪和处理顾客的订单。 1. …

骨传导耳机哪个牌子值得入手?精选热销榜TOP5推荐!

短短数年&#xff0c;骨传导耳机的市场规模迅速扩大&#xff0c;其受欢迎程度可见一斑。但身为拥有十二年经验的音频专家&#xff0c;我在此有义务提醒大家&#xff0c;在选择骨传导耳机时一定要谨慎。面对市面上的众多品牌&#xff0c;一定不要盲目入手&#xff0c;不然很容易…

webStorm debug vue项目的两种方案

一、前言 本文将介绍通过webstorm对vue项目进行debugger调试的两种方案。 但是&#xff0c;不管通过那种方案&#xff0c;都无法达到类似后端idea调试的体验&#xff0c;感觉十分难受&#xff0c;不过&#xff0c;比起用console.log还是好一些。如果各位有更好的方案&#xf…

无视OpenAI限制:智创聚合API的稳定服务承诺

近期OpenAI的一则消息——终止对中国提供API服务&#xff0c;无疑给许多依赖其技术的企业和开发者带来了不小的困扰。但别担心&#xff0c;智创聚合API平台始终在这里&#xff0c;为您提供稳定、可靠且经济的AI服务。 稳定服务&#xff0c;不受限制 智创聚合API平台的服务器设在…

酒水公司网站品牌建设宣传如何进行

红酒、白酒、啤酒、米酒、精酿啤酒等各种各样的酒水类型和从业公司数量比较多&#xff0c;部分品牌有收藏价值/价格高但销量相对较低&#xff0c;也有部分属于亲民&#xff0c;价格低但销量高&#xff0c;国内外受众广&#xff0c;人员标签不同生意拓展面自然也不同。 无论如何…

开源模型应用落地-FastAPI-助力模型交互-WebSocket篇(四)

一、前言 使用 FastAPI 可以帮助我们更简单高效地部署 AI 交互业务。FastAPI 提供了快速构建 API 的能力,开发者可以轻松地定义模型需要的输入和输出格式,并编写好相应的业务逻辑。 FastAPI 的异步高性能架构,可以有效支持大量并发的预测请求,为用户提供流畅的交互体验。此外,F…

100岁躺平计算器:规划您的长期财务未来

100岁躺平计算器:规划您的长期财务未来 在这个快节奏的世界里,我们经常忽视了长期财务规划的重要性。今天,我要向大家介绍一个有趣而实用的工具——“100岁躺平计算器”。由我开发的这个小程序可以帮助你直观地了解从现在到100岁的财务状况。 下载地址 链接: https://pan.b…

新能源电燃灶:变革与优势

在当今社会&#xff0c;能源问题日益凸显&#xff0c;能源危机成为了全球关注的焦点。而在厨房领域&#xff0c;一种名为新能源电燃灶的产品正逐渐走进人们的视野&#xff0c;以华火电燃灶为例&#xff0c;它展现出了令人瞩目的特点和潜力。 随着传统能源的逐渐枯竭和环境压力的…

Android源码——Handler机制(一)

Android源码——Handler机制&#xff08;一&#xff09; Handler机制概述介绍Handler机制模型Handler机制架构 Handler机制源码解析ActivityThreadLooperHandler Handler机制概述 介绍 Handler是Android消息机制的上层接口。Handler可以将一个任务切换到Handler所在的线程中去…

高考填报志愿,是选就业前景?还是选自己的兴趣爱好?

一、 当前的就业形式 受yi情影响&#xff0c;全国的就业处于下滑趋势&#xff0c;互联网和实体企业呈现疲软势态&#xff0c;很多企业不得不裁员。大学毕业生人数几乎每年都会上涨&#xff0c;带来的是僧多粥少的就业状态。 考得好不如报得好 就业环境如此严峻的形势下&#…

领夹麦克风哪个品牌好?揭秘无线领夹麦克风哪个品牌性价比高?

随着短视频、直播等行业的兴起&#xff0c;越来越多小伙伴开始加入自媒体创作之中&#xff0c;虽说目前手机的拍摄效果已经能满足个人创作视频的需求了&#xff0c;但是声音效果依旧是目前拍摄的瓶颈之一&#xff0c;因为手机的麦克风受限于体积&#xff0c;物理位置以及技术等…

Spring Session将HttpSession保存到Redis中,实现重启应用会话不丢失

这篇文章介绍一下在springboot项目中整合Spring Session&#xff0c;将session会话信息保存到Redis中&#xff0c;防止重启应用导致会话丢失。 第一步 创建一个springboot项目&#xff0c;添加spring-session-redis的依赖&#xff0c;因为要用到reids&#xff0c;所以要把redi…

推荐金顺心贸易一款爆款产品——越南进口高蛋白莲城鱼露

今日推荐金顺心贸易有限公司买的很火爆的一款越南高蛋白莲城鱼露&#xff0c;蛋白质含量高达30℃,天然发酵,非调制鱼露可比的。越南原装进口&#xff0c;品质纯正。

vxe-vxeTable使用vxe-colgroup分组合并表头,基础上合并

1.例 vxe-colgroup分组完成&#xff0c;需要实现两个合并合并成一行 基础合并完成 2.实现思路 由于表头字段固定&#xff0c;在进行vxe-colgroup分组合并&#xff0c;实现基础的表头合并&#xff1b;组件库官网对于表头合并并没有方法&#xff1b; 1.官网API知可以给对应的表…

炫云云渲染c4d使用教程

c4d是一款功能强大的三维建模、动画和渲染软件&#xff0c;在电影、电视和广告行业中被广泛应用于视觉效果制作&#xff0c;是一款非常受欢迎的三维设计软件&#xff0c;而后期的渲染往往又非常费时间。本文为大家介绍炫云云渲染的使用方法&#xff0c;能极大提升你的渲染效率和…

为什么ISO 45001职业健康安全管理体系是企业发展的基石

ISO 45001源自OHSAS 18001职业健康和安全管理体系&#xff0c;是全球第一个国际职业健康和安全管理标准。ISO&#xff08;国际标准化组织&#xff09;于2018年发布了这一标准&#xff0c;旨在帮助各类组织为员工提供一个更安全、更健康的工作环境。与OHSAS 18001相比&#xff0…

亚马逊测评干货分享:跨境卖家店铺测评技巧

测评在亚马逊、etsy、temu、速卖通、vinted、ebay、allegro、Jumia、Fruugo、敦煌、shopee、ozon、阿里国际站、沃尔玛、newegg等跨境平台中扮起着重要的方式&#xff0c;卖家们了解到测评可以快速增加产品的销量、评论数量&#xff0c;提升排名&#xff0c;从而打造爆款产品。…

python办公自动化之excel

用到的库&#xff1a;openpyxl 实现效果&#xff1a;读取单元格的值&#xff0c;写入单元格 代码&#xff1a; import openpyxl # 打开现有工作簿 workbookopenpyxl.load_workbook(现有工作簿.xlsx) # 选择一个工作表 sheetworkbook[交易表] # 读取单元格的值 cell_valueshe…