【Java算法】滑动窗口 下

   🔥个人主页: 中草药

🔥专栏:【算法工作坊】算法实战揭秘


🦌一.水果成篮

题目链接:904.水果成篮

算法原理

算法原理是使用“滑动窗口”(Sliding Window)策略,结合哈希表(Map)来高效地统计窗口内不同水果的种类数量。以下是详细分析:

  1. 初始化:创建一个空的哈希表 map 用来存储每种水果的数量,初始化左右指针 leftright 为 0,同时初始化结果变量 ret 为 0,用于记录最大的水果段长度。

  2. 扩展右边界:右指针 right 逐渐向右移动,每移动一步,就在哈希表 map 中增加对应水果的数量。这代表尝试将新的水果加入当前的采摘窗口。

  3. 处理超过两种水果的情况:使用 while 循环检查哈希表 map 的大小是否大于 2,即窗口内是否含有超过两种水果。如果是,则需要收缩左边界,即从窗口中移除最左边的水果(即减少其在哈希表中的计数,并在计数为 0 时从哈希表中移除该水果),然后将左指针 left 向右移动一位,缩小窗口范围。

  4. 更新结果:每次右指针移动后,都检查当前窗口(right-left+1)的长度是否大于之前记录的最大长度 ret,如果是,则更新 ret 为当前窗口的长度。

  5. 遍历结束:当右指针遍历完整个数组后,ret 中存储的就是能够收集到的、每个篮子中只含有两种类型水果的最长连续段的长度。

时间复杂度与空间复杂度

  • 时间复杂度:O(n),其中 n 是数组 fruits 的长度。每个元素最多被遍历一次。
  • 空间复杂度:O(1),虽然使用了哈希表,但由于最多只存储两种类型的水果,所以哈希表的大小是常数级别,整体空间复杂度为 O(1)。

代码

public int totalFruit(int[] fruits) {
        Map<Integer,Integer> map=new HashMap<>();
        int ret=0;
        for(int left=0,right=0;right<fruits.length;right++){
            map.put(fruits[right],map.getOrDefault(fruits[right],0)+1);
            while(map.size()>2){
                map.put(fruits[left],map.get(fruits[left])-1);
                if (map.get(fruits[left])==0){
                    map.remove(fruits[left]);
                }
                left++;
            }
            ret=Math.max(ret,right-left+1);
        }
        return ret;
    }

 举例

测试用例 [1,2,3,2,2]

初始状态

  • 初始化 left = 0right = 0ret = 0,以及一个空的哈希表 map 用于记录每种水果的数量。

执行过程

  1. 右指针移动与计数

    • 当 right = 0fruits[right]=1,哈希表变为 {1:1}
    • 当 right = 1fruits[right]=2,哈希表变为 {1:1, 2:1}
    • 当 right = 2fruits[right]=3,哈希表变为 {1:1, 2:1, 3:1}。此时哈希表大小超过2,触发左指针移动。
  2. 左指针移动与计数调整

    • 移动 left,从 left = 0 开始,哈希表变为 {1:0, 2:1, 3:1},然后移除键值对 {1:0},哈希表变为 {2:1, 3:1},此时 left = 1
  3. 继续右指针移动

    • 当 right = 3fruits[right]=2,哈希表变为 {2:2, 3:1}
    • 当 right = 4fruits[right]=2,哈希表变为 {2:3, 3:1}。此时窗口内还是两种水果,不触发左指针移动。

结果计算

  • 在整个过程中,不断更新 ret 以记录最长子数组长度。当右指针遍历结束时,ret 记录的是满足条件的最长子数组长度。
  • 对于测试用例 [1,2,3,2,2],最长的连续子数组内包含两种水果的最大长度为从索引1到4,即 [2,3,2,2],长度为4。

返回结果

  • 因此,这段代码在处理完测试用例后返回的结果是 4

🦣二.找到字符串中的所有字母异位词

题目链接:438.找到字符串中所有字母异位词

算法原理

  1. 初始化:首先将输入的字符串 sspp 分别转换成字符数组 sp,便于后续操作。然后,创建两个大小为 26 的整型数组 hash1hash2 作为哈希表,用于记录字符计数。hash2 用于预存储字符串 pp 中各字符出现的频次。

  2. 预处理:遍历字符串 pp,在 hash2 中记录每个字符出现的次数。比如,如果 pp 是 "abc",那么 hash2['a' - 'a'](即 hash2[0])将增加 1,以此类推。

  3. 滑动窗口遍历

    • 使用两个指针 left 和 right 初始化为 0,定义一个 count 记录当前窗口内满足条件的字符数量。
    • 当 right 指针遍历 s 时,更新 hash1 中对应字符的计数,并检查如果该字符的计数不大于 hash2 中的计数,则增加 count
    • 当窗口大小(right - left + 1)超过 pp 的长度时,说明需要收缩窗口左侧。此时,检查 left 指针所指字符的计数,如果它之前满足条件(即计数不大于 hash2 中的计数),则减少 count,并减少 hash1 中该字符的计数,然后 left 指针右移。
    • 当窗口内满足条件的字符数 count 等于 pp 的长度时,说明找到了一个异位词,将 left 索引添加到结果列表 ret 中。
  4. 返回结果:遍历结束后,返回存储了所有异位词起始索引的列表 ret

时间复杂度与空间复杂度

  • 时间复杂度:O(N),其中 N 为字符串 ss 的长度。每个字符最多被遍历一次。
  • 空间复杂度:O(1),虽然使用了两个大小为 26 的数组作为哈希表,但它们的空间需求是固定的,不依赖于输入字符串的大小。

代码

   public List<Integer> findAnagrams(String ss, String pp) {
        List<Integer> ret= new ArrayList<>();
        char[] s=ss.toCharArray();
        char[] p=pp.toCharArray();
        int[] hash1=new int[26];
        int[] hash2=new int[26];
        //将pp对照的范本储存在hash2
        for (char a:p){
            hash2[a-'a']++;
        }
        int len=p.length;
        for(int left=0,right=0,count=0;right<s.length;right++){
            hash1[s[right]-'a']++;
            if (hash1[s[right]-'a']<=hash2[s[right]-'a']){
                count++;
            }
            if (right-left+1>len){
                if (hash1[s[left]-'a']<=hash2[s[left]-'a']){
                    count--;
                }
                hash1[s[left++]-'a']--;
            }
            if (count==len){
                ret.add(left);
            }
        }
        return ret;
    }

举例

测试用例 s = "cbaebabacd" ; p ="abc"
  1. 初始化: 定义两个长度为 26 的列表 hash1hash2 用于存储字符计数。hash2 用于存储模式字符串 p 中每个字符出现的次数。

  2. 构建模式哈希: 遍历模式字符串 p,并使用 ASCII 值减去 'a' 的 ASCII 值作为索引来记录每个字符的出现次数到 hash2 中。

  3. 双指针遍历:

    • 初始化两个指针 left 和 right 以及一个计数器 count 来追踪当前窗口是否为有效异位词。
    • 使用 right 指针向右移动,增加右侧字符在 hash1 中的计数,如果该字符的计数小于等于 hash2 中的计数,则增加 count
    • 当窗口大小(即 right - left + 1)超过模式字符串长度时,说明需要收缩窗口:
      • 减少左侧字符在 hash1 中的计数,如果之前该字符的计数也小于等于 hash2 中的计数,则减少 count
      • 左指针 left 向右移动一位,缩小窗口。
    • 检查 count 是否与模式字符串长度相等,如果相等则说明当前窗口是一个有效异位词,记录下其起始索引 left
  4. 收集结果: 所有满足条件的起始索引被收集到列表 ret 中,并最终返回。

现在,针对给定的测试用例:

  • 字符串 s = "cbaebabacd"

  • 模式 p = "abc"

  • 遍历开始,首先构建 hash2hash2 对于 "abc" 会是 [1, 1, 1](因为每个字符出现一次)。

  • 双指针开始滑动:

    • 当 right = 0 时,"c" 计数增加,但不满足异位词条件(因为没有比较字符)。
    • 移动到 "b" (right = 1),此时窗口 "cb",仍然不构成异位词。
    • 添加 "a" (right = 2),窗口变为 "cba",这时 hash1 与 hash2 匹配(各字符计数都是 1),因此 count = 3(与模式长度相等),记录索引 0
    • 继续滑动,当 "e" 进入窗口时(right = 3),由于它不在模式中,之前 "c" 的计数减一并不影响 count(仍为 3),但窗口大小已超过模式长度,所以收缩左侧。
    • 收缩窗口时,移除 "c" (left = 1),检查并可能更新 count,但在这个例子中,直到 "b" (left = 2) 被移除时 count 才会减少,因为它与模式中的字符匹配。
    • 当窗口滑动到最后,到达 "bac"(在原字符串中的位置为索引 6 开始),再次满足异位词条件,记录索引 6

最终,函数正确返回了异位词子串的起始索引 [0, 6],这与我们的手动分析相符。

🐮三.串联所有单词的子串

题目链接:30.串联所有单词的子串

算法原理

  1. 初始化:

    • 创建一个结果列表 ret 用来存放符合条件的子串起始索引。
    • 创建一个哈希表 hash1 来记录单词数组 words 中每个单词出现的次数。
    • 计算单个单词的长度 len 和单词数组的大小 size
  2. 构建单词频率哈希表:

    • 遍历 words 数组,使用哈希表 hash1 记录每个单词及其出现次数。
  3. 滑动窗口遍历字符串:

    • 以单词长度 len 为步长,从字符串 s 的每个可能的起始位置开始滑动窗口。
      • 对于每个起始位置 i,初始化一个新的哈希表 hash2 来记录窗口内各个单词的出现次数。
      • 使用两个指针 left 和 right 表示窗口的左右边界,初始时 left = right = i
      • 移动 right 指针,每次向右移动 len 个单位,将新进入窗口的单词 in 计数加入 hash2
        • 如果 hash2 中 in 的计数不大于 hash1 中的计数,说明当前单词匹配成功,计数器 count 加一。
      • 当窗口大小(即 right - left + 1)超过所有单词组合的总长度(即 len * size)时:
        • 移出窗口最左边的单词 out,更新 hash2 并相应减少 count(如果必要)。
        • 同时,左边界 left 向右移动 len 个单位,缩小窗口。
      • 如果 count 等于 size,说明窗口内的单词完全匹配了 words 中的所有单词(考虑顺序和数量),将 left 索引添加到结果列表 ret 中。
  4. 返回结果: 遍历完成后,返回包含所有符合条件子串起始索引的列表 ret

时间复杂度分析

  • 外层循环遍历字符串 s,时间复杂度为 O(n),其中 n 是字符串 s 的长度。
  • 内层循环虽然也是遍历字符串,但由于每次滑动窗口实际上是在“跳跃”(每次跳过一个单词长度),其复杂度受到单词长度和单词数组大小的影响,大致可视为 O(m*k),其中 m 是单词数组的大小,k 是单个单词的平均长度。
  • 因此,总体时间复杂度大约为 O(nmk)。

空间复杂度

  • 主要由哈希表占用,空间复杂度为 O(m+k),其中 m 是单词数组的大小,k 是不同单词的数量(在极端情况下,所有单词都不重复)。

代码

public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> ret = new ArrayList<>();
        Map<String,Integer> hash1=new HashMap<>();
        int len=words[0].length();
        int size=words.length;
        for(String str:words){
            hash1.put(str,hash1.getOrDefault(str,0)+1);
        }
        for(int i=0;i<len;i++){
            Map<String,Integer> hash2=new HashMap<>();
            for(int left=i,right=i,count=0;right+len <=s.length();right+=len){
                String in=s.substring(right,right+len);
                hash2.put(in,hash2.getOrDefault(in,0)+1);
                if(hash2.get(in)<=hash1.getOrDefault(in,0)){
                    count++;
                }
                if(right-left+1>len*size){
                    String out=s.substring(left,left+len);
                    if(hash2.get(out)<=hash1.getOrDefault(out,0)){
                    count--;
                    }
                    hash2.put(out,hash2.get(out)-1);
                    left+=len;
                }
                if(count==size){
                    ret.add(left);
                }
            }
        }
            return ret;
    }

举例

测试用例 s ="barfoofoobarthefoobarman";words =["bar","foo","the"]
  1. 初始化:

    • 初始化结果列表 ret
    • 创建哈希表 hash1 存储单词及其计数,初始化为空。
    • 单词长度 len = 3(因为 words[0].length() 是 "bar" 的长度)。
    • 单词数组大小 size = 3(因为有三个单词)。
    • 遍历 words,填充 hash1,使其内容为 {bar=1, foo=1, the=1}
  2. 滑动窗口遍历:

    • 关键在于理解滑动窗口如何准确地识别出所有匹配的子串起始位置。

    • 第一个匹配:

      • 窗口从索引 0 开始,但首个匹配实际上从索引 6 开始,因为 "foobarthefoobarman" 中从索引 6("f") 开始的子串包含了 "foo""bar""the"(按照 "foobarthe" 的顺序)。此时,count 达到 size(3),因此 6 被添加到结果列表中。
    • 第二个匹配:

      • 窗口继续右移,当右边界达到索引 9 时,子串变为 "oobarthefoo",其中包含了另一个 "foo""bar""the" 序列(注意,尽管 "foo" 重叠,但因为我们是寻找无序的组合,所以依然有效)。此时,也会触发 count == size,因此索引 9 被记录。
    • 第三个匹配:

      • 最后一个匹配发生在索引 12,从这里开始的子串为 "obarfoobarman",同样包含了所需的三个单词(忽略顺序)。因此,索引 12 也被加入结果列表。
  3. 结果收集:

    • 正确的输出是 [6, 9, 12],这三个位置开始的子串分别包含了给定单词数组 ["bar", "foo", "the"] 中所有单词的一个排列。

 

🐏 四.最小覆盖串

题目链接:76.最小覆盖子串

算法原理

  1. 初始化:

    • 将输入字符串 ss 和 tt 转换为字符数组 s 和 t 以便于操作。
    • 初始化两个哈希表(在这里使用整型数组 hash1 和 hash2)来记录字符出现的次数。数组的索引对应字符的 ASCII 码值,值表示字符出现的次数。
    • 初始化变量 kind 记录需要匹配的字符种类数(即 tt 中不同字符的数量),初始化最小长度 minlen 为最大整数值,记录子串起始索引 begin 为 -1
    • 遍历字符串 tt,统计每个字符的出现次数到 hash1,同时增加 kind 的值,表示需要匹配的字符种类。
  2. 滑动窗口遍历:

    • 使用两个指针 left 和 right 构成一个滑动窗口,初始时 left = right = 0
    • 当 right 指针遍历 s 时,对进入窗口的字符 in 增加 hash2 的计数,若该字符在 hash2 中的计数等于其在 hash1 中的计数,则说明这个字符已经匹配完成,增加计数器 count
    • 当 count 等于 kind 时,说明窗口内的字符已经包含了 tt 中所有字符至少各一次,此时尝试缩小窗口以寻找最小覆盖子串:
      • 检查当前窗口长度是否小于已记录的最小长度 minlen,若是,则更新 minlen 和子串起始索引 begin
      • 然后,从窗口左侧移除字符 out(即 s[left]),并更新 hash2 和 count,随后移动 left 指针向右,继续寻找可能更小的覆盖子串。
  3. 结果处理:

    • 循环结束后,检查是否有找到符合条件的子串,如果没有(即 begin == -1),返回空字符串;否则,返回 ss 中从 begin 开始长度为 minlen 的子串。

算法特性

  • 时间复杂度: O(N),其中 N 是字符串 ss 的长度。每个字符最多被访问两次:一次作为窗口的右边界,一次作为窗口的左边界。
  • 空间复杂度: O(1),尽管使用了额外的哈希表,但因为字符集固定(ASCII码范围),所以空间复杂度是常数级别的。

代码

 public String minWindow(String ss, String tt) {
        char[] s=ss.toCharArray();
        char[] t=tt. toCharArray();
        int[] hash1=new int[128];
        int[] hash2=new int[128];
        int kind=0;
        int minlen=Integer.MAX_VALUE;
        int begin=-1;
        for(char ch:t){
           if(hash1[ch]++==0)kind++; 
        }
        for(int left=0,right=0,count=0;right<s.length;right++){
            char in=s[right];
            if(++hash2[in]==hash1[in])count++;
            while(kind==count){
                if(right-left+1<minlen){
                    begin=left;
                    minlen=right-left+1;
                }
                char out=s[left];
                if(hash2[out]--==hash1[out])count--;
                left++;
            }
        }
        if(begin==-1){
            return new String(); 
        }
        return ss.substring(begin,begin+minlen);
    }

举例

测试用例 s ="ADOBECODEBANC" ; t ="ABC"
  1. 初始化:

    • 将字符串 s 和 t 转换为字符数组。
    • 初始化两个长度为 128 的数组 hash1 和 hash2 作为哈希表,记录字符出现次数。
    • 初始化变量 kind 为 0,用于记录目标字符串 t 中不同字符的种类数;minlen 设置为 Integer.MAX_VALUE,用于记录最小覆盖子串长度;begin 设置为 -1,用于记录最小覆盖子串的起始位置。
    • 遍历目标字符串 t,对 hash1 进行填充并计算种类数 kind。在此例中,hash1['A'] = 1hash1['B'] = 1hash1['C'] = 1,因此 kind = 3
  2. 滑动窗口遍历:

    • 使用双指针 left 和 right 构建滑动窗口,初始时 left = 0right = 0count = 0
    • 遍历字符串 s
      • 当右指针 right 移动时,遇到的字符 in = s[right],在 hash2 中计数递增,如果这个递增使得 hash2[in] 等于 hash1[in],说明字符 in 已经匹配完成,于是 count++
      • 当 count 等于 kind 时,说明窗口内的字符已经包含了 t 中所有字符至少各一次。此时开始收缩窗口:
        • 检查当前窗口长度是否小于 minlen,若是,则更新 minlen 和 begin
        • 移除窗口左侧的字符 out = s[left],在 hash2 中对应的计数递减,如果递减后 hash2[out] 等于 hash1[out],说明移除的字符不再满足匹配条件,于是 count--
        • 然后 left++,继续检查下一个可能的窗口。
    • 在这个过程中,对于测试用例,窗口会遍历并调整位置,直到找到包含 "ABC" 所有字符的最小子串。具体来说,当窗口覆盖 "BANC" 时,满足条件,此时 count = 3,并且窗口长度是最小的。
  3. 结果处理:

    • 最终,当遍历结束,如果找到了有效的子串(即 begin != -1),根据记录的 begin 和 minlen 截取并返回最小覆盖子串。对于给定测试用例,返回结果是 "BANC"

🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀

以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐

  制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸

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

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

相关文章

SD卡无法读取:原因解析与数据恢复策略

一、SD卡无法读取的尴尬场景 在数字化日益普及的今天&#xff0c;SD卡作为便携式存储设备&#xff0c;广泛应用于各类电子设备中。然而&#xff0c;当您急需访问SD卡中的数据时&#xff0c;却发现设备无法读取SD卡&#xff0c;这无疑是一个令人沮丧的场景。SD卡无法读取可能表…

SUSE linux 15的网络管理

1 手工配置网络 wicked提供了一种新的网络配置框架。自SUSE 12起&#xff0c;SUSE使用了新的网络管理工具wicked&#xff0c;这个是区别与其他常见发行版的。常见的发行版目前大多使用的是NetworkManager服务进行网络管理。 1.1 wicked网络配置 传统网络接口管理面临的挑战之…

段,页,段页,三种内存(RAM)管理机制分析

段&#xff0c;页&#xff0c;段页 是为实现虚拟内存而产生的技术。直接使用物理内存弊端&#xff1a;地址空间不隔离&#xff0c;内存使用效率低。 段 段&#xff1a;就是按照二进制文件的格式&#xff0c;在内存给进程分段&#xff08;包括堆栈、数据段、代码段&#xff09;。…

Python 算法交易实验72 QTV200第一步: 获取原始数据并存入队列

说明 最近的数据流往前进了一步&#xff0c;我觉得基本可以开始同步的推进QTV200了。上次规划了整体的数据流&#xff0c;现在开始第一步。 内容 1 结构位置 这是上次的总体图&#xff1a; 以下是这次要实现的一小部分&#xff1a; 从结构上&#xff0c;这个是整体数据流的…

每日AI资讯-20240622

1. 可灵AI全新功能上线&#xff01; 可灵AI全新功能上线&#xff01;图生视频和视频续写来啦&#xff01; 图生视频&#xff1a;上传任意图片&#xff0c;生成5秒精彩视频。支持添加提示词控制图像运动视频续写&#xff1a;对生成视频一键续写4&#xff5e;5秒&#xff0c;支持…

LeetCode:经典题之1491、896 题解与延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 …

基于uni-app和图鸟UI开发上门服务小程序

一、技术栈选择 uni-app&#xff1a;我们选择了uni-app作为开发框架&#xff0c;因为它基于Vue.js&#xff0c;允许我们编写一次代码&#xff0c;发布到多个平台&#xff0c;包括iOS、Android、Web以及各种小程序。uni-app的丰富组件库、高效的状态管理以及便捷的预览调试功能&…

LightGBM算法详解

LightGBM算法详解 LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是由微软开发的高效梯度提升决策树&#xff08;GBDT&#xff09;实现。它以速度和效率著称&#xff0c;特别适用于大规模数据集和高维特征的场景。本文将详细介绍LightGBM的原理、特点、常用…

用于世界上最先进的医疗应用的精密电阻器

EAK的高性能电阻器使医疗产品设计人员能够继续改善全球患者的生活质量。我们的电阻器专为用于医疗诊断、治疗和预防的各种产品而设计。从小型植入式和非侵入性设备到大型诊断成像设备&#xff0c;医疗制造商之所以选择EAK 电阻器&#xff0c;是因为操作环境是高电压和磁场&…

AI-算力产业链之存力

在数字经济大潮下&#xff0c;数据已经成为新型的生产资料。 目前数据中心有三大力量&#xff1a;计算的力量——算力、存储的力量——存力、运输的力量——运力&#xff0c;即网络的力量。 算力产业链正在火热发展的同时&#xff0c;存力的需求也大幅度提升。2023年上半年&…

总结 CSS 选择器的常见用法

一&#xff0c;什么是css 在前端网页中&#xff0c;css就相当于化妆术&#xff0c;把一个很生硬的网页页面变得排版有序起来。 CSS可以对网页中的元素位置进行像素级精准控制&#xff0c;实现美化页面的效果&#xff0c;也能做到页面的样式和结构分离。 二&#xff0c;css的基…

MySQL中的ibd2sdi—InnoDB表空间SDI提取实用程序

ibd2sdi 是一个用于从 InnoDB 表空间文件中提取序列化字典信息&#xff08;Serialized Dictionary Information, SDI&#xff09;的实用程序。这个实用程序可以用于提取存储在持久化 InnoDB 表空间文件中的 SDI 数据。 可以对以下类型的表空间文件使用 ibd2sdi&#xff1a; 每…

消息认证码解析

1. 什么是消息认证码 消息认证码(Message Authentication Code)是一种确认完整性并进行认证的技术&#xff0c;取三个单词的首字母&#xff0c;简称为MAC。 消息认证码的输入包括任意长度的消息和一个发送者与接收者之间共享的密钥&#xff0c;它可以输出固定长度的数据&#x…

C语言之详解预处理

前言&#xff1a; 预处理也叫预编译&#xff0c;是编译代码时的第一步&#xff0c;经过预处理后生成一个.i文件&#xff0c;如果不明白编译与链接作用的小伙伴可以先看看博主的上一篇博客—— &#xff0c;不然知识连贯性可能会显得很差哦。 正文目录&#xff1a; 预定义符号#…

discuz迪恩cul!教育课程培训网站模板

Discuz x3.2模板 迪恩cul!教育课程培训 GBK&#xff0c;程序包中内附详细的安装教程&#xff0c;下载后按照教程安装即可 discuz迪恩cul!教育课程培训网站模板

qemu 安装ubuntu22.04虚拟机 -纯命令行-可ssh-带网络-编译安装 linux kernel-编译安装 kernel module

tar -xjf xxx.tar.bz2 1&#xff0c;预备系统盘数据 1.1 下载光盘 注意需要 liver-server $ wget https://releases.ubuntu.com/22.04.4/ubuntu-22.04.4-live-server-amd64.iso 1.2 挂载并拷贝 $ sudo mkdir /mnt/iso_ubuntu-22.04.4-live-server-amd64 $ sudo mount u…

星闪指向遥控,做家电交互的破壁人

“面壁者罗辑&#xff0c;我是你的破壁人。” 科幻小说《三体》中&#xff0c;当人类的基础科学被三体人封锁&#xff0c;变得停步不前&#xff0c;人类启动了自救的面壁计划&#xff0c;通过一次又一次破壁&#xff0c;找到战胜三体人的办法。 现实中&#xff0c;有一点已经成…

html--好看的手机充值单页

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>线上充值-首页</title><meta content"widthdevice-width,initial-scale1.0,maximum-scale1.0,user-scalable0" name"viewport&…

【Vue-Vben-Admin】1、初次运行和介绍

【Vue-Vben-Admin】1、初次运行和介绍 Vben-Admin 初次运行和介绍 小小的介绍规定版本文件树安装依赖运行项目 小小的介绍 一款 Vue3 Typescript4 Vite2 后台管理项目&#xff0c;功能挺多的&#xff0c;还有组件库 规定版本 此个人文档规定版本为 2.8.0&#xff0c;可能版本…

AI大模型企业应用实战(16)-langchain核心组件

1 stuff 将文档列表插入到提示词中&#xff0c;适合文档较小或少量文档的应用。 2 refine 通过循环输入文档并迭代更新答案来构建响应&#xff0c;一次只传递给LLM一个文档&#xff0c;适合LLM上下文大小不能容纳的小文档。 参考&#xff1a; https://js.langchain.com/v0.1…