滑動窗口算法專題

滑動窗口簡介??

滑動窗口就是利用單調性,配合同向雙指針來優化暴力枚舉的一種算法。?

?該算法主要有四個步驟

1. 先進進窗口

2. 判斷條件,后續根據條件來判斷是出窗口還是進窗口

3. 出窗口

4.更新結果,更新結果這個步驟是不確定的,應題目要求判斷是在進窗口前更新結果還是出窗口前更新結果。

1. 長度最小的子數組

題目鏈接:209. 長度最小的子數組 - 力扣(LeetCode)

題目細節信息:

1.數組中都是正數? ?2.在數組中找到長度最小的子數組且子數組中的元素和小于target值?

解法:滑動窗口

我們先定義一個left指針和right指針,left和right之間就是一個窗口。在定義一個變量sum來記錄[left,right]區間的和。

根據題目要求,我們先確定第一個sum大于等于target值得右邊界,所以我們先讓right不斷進窗口。

以題目中的實例1為例

接著我們根據sum的值來判斷是否進窗口還是出窗口。sum的值無非會遇到兩種情況。

當sum小于等于target的時候,我們先要更新最小長度和sum的值,接著在進窗口,即讓left++?

如下圖:?

之前left指向的元素已經不在窗口里面了,這也是理解出窗口的一個圖解。

當sum小于target時,我們進窗口進行了,即right++?

滑動窗口的正確性

為什么能判斷滑動窗口是對的呢?

因為數組中的數據都是正數,當right找到第一個邊界使sum大于等于target的值時,我們就沒必要讓right繼續向后走了,因為數組中都是正數,right繼續走下去,sum會變大,但是len也會變長,此時len肯定就不是我們要的結果了。所以不讓right向后走,就避免了其他不符合題意情況的枚舉了。?

代碼實現

代碼一:我寫的形式

    public int minSubArrayLen(int target, int[] nums) {int n=nums.length;int left=0,right=0;int ret=Integer.MAX_VALUE;int sum=nums[right];while(right<n){if(sum<target){right++;//進窗口if(right<n){sum+=nums[right];}}else{ret=Math.min(ret,right-left+1);//更新長度最小值sum-=nums[left];//更新sum值left++;//出窗口}}return ret==Integer.MAX_VALUE?0:ret;}

代碼二:

    public int minSubArrayLen(int target, int[] nums) {int n=nums.length;int len=Integer.MAX_VALUE;int sum=0;for(int left=0,right=0;right<n;right++){//進窗口sum+=nums[right];while(sum>=target){//這里要用while循環len=Math.min(len,right-left+1);//更新最小長度sum-=nums[left];//更新sum的值left++;//出窗口}}return len==Integer.MAX_VALUE?0:len;}

2.無重復字符的最長字串?

題目鏈接:3. 無重復字符的最長子串 - 力扣(LeetCode)?

題目解析:在字符串中找到一個連續且無重復字符的子字符串,并返回其長度。

解法一:暴力枚舉(會超時)

枚舉從字符串的第一個字符開始往后,無重復字符的子串可以到什么位置,找出一個最大長度的即可。

因此,我們可以通過一個哈希表來記錄往后枚舉的過程中,字符是否出現重復的情況。

//時間復雜度O(n^2)
//空間復雜度O(1)
import java.util.*;
class Solution {public int lengthOfLongestSubstring(String s) {int len = s.length();int ret = 0;for(int i = 0; i < len; i++) {int[] hash = new int[128];for(int j = i; j < len; j++) {hash[s.charAt(j)]++;if(hash[s.charAt(j)] > 1) {break;}ret = Math.max(ret, j - i + 1);}}return ret;}
}

解法二:滑動窗口

此時,我們可以通過滑動窗口來優化上面的暴力枚舉。

首先,先通過一種枚舉的情況來分析,如下圖

當我們枚舉時,當right遇到第一個重復的字符a時,我們就不必要讓right繼續往后走了,因為前面的left的位置沒變,當right繼續往后走,left和right之間是一定有重復的字符的。

所以,此時,我們可以讓right先固定在原地,先讓left指針往后走,直到left指針跳過重復的字符,right才能繼續完后走。

但是,當left往后走的時候,right沒必要往回退到和left一樣的位置,因為當left沒有跳過第一個重復的字符時,right撐死只能走到第二個a的位置,且left往后走了,此時子串的長度肯定是比left沒有往后走時短的。

兩個指針沒有回退,這時就可以使用滑動窗口了。

這里先解釋下上面的hash數組的意思

這里hash數組的下標為字符串中字符的ASCII值,hash數組中的數據是該字符的出現次數。?

滑動川口的解題步驟:

1.進窗口:讓字符進入hash表中

2.判斷和出窗口:判斷該字符是否重復出現,如果重復出現,則出窗口,即將該字符從hash表中刪除。

3.更新結果:這里是先進行判斷后,才執行更新的操作。

代碼實現:

時間復雜度:O(n)
空間復雜度:O(n)public int lengthOfLongestSubstring(String ss) {int n=ss.length();char[] s=ss.toCharArray();int[] hash=new int[128];int left=0,right=0,ret=0;while(right<n){hash[s[right]]++;//進窗口while(hash[s[right]]>1){//判斷字符是否重復出現hash[s[left++]]--;//出窗口}ret=Math.max(ret,right-left+1);//更新結果right++;}return ret;        }

3. 最大連續1的個數

題目鏈接:1004. 最大連續1的個數 III - 力扣(LeetCode)

題目解析:最多可以將數組中的k個0翻轉為1,返回數組經過翻轉后,數組中連續1的最大個數。

雖然題目中是要求我們翻轉0,但是如果我們遇到0就將其翻轉為1的話,接著進行新的枚舉的時候,就又要將翻轉過的0,重新翻轉為0,此時,代碼就會很難寫,且很復雜。

其實,我們可以轉換為求區間的長度,只要該區間的0的個數沒有大于k個就行了。

解法一:暴力枚舉+zero計數器

定義一個left和right指針,我們可以讓left為起點向后枚舉,定義一個zero變量來保存枚舉過程中遇到0的個數?,如果zero的值大于k,此時我們就可以讓right指針停在該位置了,因為此時right如果繼續走下去,left和right區間就是不符合題目要求了。

也就是說,此時以left為起點的枚舉,得到的連續1的長度就是一個最優解了,此時就可以更新結果

所以,我們要換一個起點進行枚舉,既讓left++,接著讓right回到left的位置,以新的left為起點繼續,right繼續向后枚舉,重復上面的步驟。

解法二:滑動窗口

再暴力枚舉上進一步優化,當我們讓left++的時候,沒必要將right重新指向left的位置,因為當zero的值大于k時,right撐死也時只能走到剛才停止的位置,只有我們left跳過一個0的時候,讓zero減一,讓zero的值小于k時,此時right才可以繼續完后枚舉。

此時,發現,left和right指針是同向運行,且不會退,我們就可以使用滑動窗口算法來解決該問題。

步驟一:進窗口

當right完后枚舉時,遇到1就忽略,如果遇到0,就讓zero的值加1

步驟二:判斷+出窗口

當zero的值大于k時,我們就出窗口,也就時讓left++,如果left遇到1就忽略,如果遇到0,就

讓zero的值減1

步驟三:更新結果

此時,更新結果的步驟是在判斷的步驟之后。?

代碼實現:

//時間復雜度:O(n)
//空間復雜度:O(1) public int longestOnes(int[] nums, int k) {int left=0,right=0,zero=0;int n=nums.length;int ret=0;while(right<n){if(nums[right]==1){right++;}else{right++;zero++;//出窗口}while(zero>k){//判斷if(nums[left]==0){zero--;//進窗口}left++;}ret=Math.max(ret,right-left);//更新結果}return ret;}

注意:這里更新結果為什么不是right-left+1呢?因為我是再right++之后再更新長度,而不是再right++之前更新長度。?

更簡練版本:

    public int longestOnes(int[] nums, int k) {int ret = 0;for(int left = 0, right = 0, zero = 0; right < nums.length; right++){if(nums[right] == 0) zero++; // 進窗?while(zero > k) // 判斷if(nums[left++] == 0) zero--; // 出窗?ret = Math.max(ret, right - left + 1); // 更新結果}return ret;}

這個版本就是再right++之前更新長度,所以更新長度時是right-left+1?

?4.將x減到0的最小操作數

題目鏈接:1658. 將 x 減到 0 的最小操作數 - 力扣(LeetCode)

題目解析:

1.我們每次進行一次刪減操作時,我們都要將數組最左邊或最右邊的元素刪去,供下一次刪減操作時使用

2.數組里面的都是正數

在該題中,只有數組里面全是正數,我們才能使用滑動窗口解決

分析:因為當數組里面有負數或者為0的數據時,當right到達第一個停止的位置時,當我們的tmp減去一個負數或者數據為0的數時,由于負數或0的緣故,會導致[left,right]區間的和有可能是等于或大于tmp的,所以,此時進行新的枚舉時,right有可能會向前退,也有可能繼續向后退。?

解題思路轉換:解決該題的時候,我們有時候會刪去最左邊的元素,有時候會刪去最右邊的元素,但是這種情況太復雜了,我們要轉換思路。

正難則反:

題目要求我們找到數組兩邊使x值減為0的最小個數,我們就可以轉換為求中間和為sum-x的最長子串。

解法一:暴力枚舉

套兩層for循環,遍歷每一個子數組的情況,根據子數組的和是否等于target的值,我們就更新結果,接著break跳出一層循環。

解法二:滑動窗口

我們通過滑動窗口來優化枚舉,我們每進行一次新的遍歷的時候,我們發現沒必要每次都讓right回到left的位置,因為數組里面都是正數,當left++之后,[left,right]區間的和肯定是小于target的。

此時,發現left和right指針都不回退,此時就可以使用滑動窗口。

1.進窗口:tmp+=nums[right]

2.判斷+出窗口:判斷tmp的值是否大于target,如果大于出窗口,即nums-=nums[left++]

3.更新結果:當tmp的值等于target的時候,我們就可以更新結果。

//時間復雜度:O(n)
//空間復雜度:O(1)public int minOperations(int[] nums, int x) {int sum=0;for(int i=0;i<nums.length;i++){sum+=nums[i];}int ret=-1;int target=sum-x;//處理細節,if(target<0) return -1;for(int left=0,right=0,tmp=0;right<nums.length;right++){tmp+=nums[right];//進窗口while(tmp>target){//判斷tmp-=nums[left++];//出窗口}if(tmp==target){ret=Math.max(ret,right-left+1);//更新結果}}if(ret==-1) return -1;//此時沒有找到子數組和為target的子數組else return nums.length-ret;}

?5.水果成籃(從這里開始比較認真)

題目連接:904. 水果成籃 - 力扣(LeetCode)?

題目分析:有一個fruit數組,在數組中,不同元素的值代表不同的水果種類,相同元素的值代表水果的種類相同,我們有兩個籃子,每個籃子只能裝一種水果,一個籃子中裝的水果數量沒有限制。如果摘水果的過程中,一旦遇到與籃子中水果種類不同的水果樹,就停止采摘,求這兩個籃子能裝的最大水果數量。?

以上可以總結為一句話:找一個連續的最長子數組,該子數組中的水果種類不超出兩種。?

解法一:暴力枚舉+哈希表?

我們可以將每一個子數組的情況枚舉出來,枚舉的過程中,我們可以借助一個hash表來保存枚舉過程中采摘水果的種類和數量。

我們用left為外層循環的標志,right為內層循環的標志

枚舉的小細節:

1. 為了防止在[1,2,1]的情況下,right指針會造成數組越界,所以我們每次進行一次內循環時,要對right指針進行判斷,是否越界。

2.當籃子中水果的種類也超出兩種時,也應該跳出該內層循環

3.在每一次采摘水果之前,必須判斷水果種類為2種時,下次采摘的水果是否為第三種水果,如果成立,則跳出內部循環

4.每次進行一次新的外部枚舉時,我們也要將hash表中上次枚舉保存水果的情況刪掉。

代碼

//空間復雜度:O(n)
//時間復雜度:O(n^2)public int totalFruit(int[] f) {Map<Integer, Integer> hash = new HashMap<Integer, Integer>();int ret = 0;for (int left = 0; left < f.length; left++) {for (int right = left; right < f.length; right++) {if (right == f.length || hash.size() > 2) {//判斷數組是否越界和水果種類的數量break;}int in = f[right];if (hash.size() == 2 && !hash.containsKey(in)) {//摘水果之前的判斷break;}hash.put(in, hash.getOrDefault(in, 0) + 1);ret = Math.max(ret, right - left + 1);}hash.clear();//在下次枚舉之前,刪除此次枚舉的情況}return ret;}

?解法二:滑動窗口

當我們進行新的left的枚舉時,我們沒必要讓right重新回到left的位置,因為當left進行新的枚舉時(left往后走),如果right重新返回到left指針的位置,往后枚舉的時候,right會出現兩種情況,第一種情況:right會停在在上一次left枚舉時,right的最后枚舉的位置或者超過right最后枚舉的位置也就是說,以新的left為新的起點,進行right的枚舉時,right是一定會經過之前的枚舉停下的位置的,所以,我們就不必要將right返回到left的位置。

通過上面的分析,發現left和right指針是同向雙指針,這時我們就可以使用滑動窗口來解決這個問題。?

解題步驟

1.定義left=0,right=0

2.進窗口:讓hash[f[right]]++

3.判斷+出窗口(一個循環):

? ? ? ? 當hash.size>2時,讓hash[f[left]]--,同時讓left++

4.更新長度?

用哈希表來實現:

//時間復雜度:O(n)
//空間復雜度:O(n)public int totalFruit(int[] f) {Map<Integer,Integer> hash=new HashMap<Integer,Integer>();int ret=0;for(int left=0,right=0;right<f.length;right++){int in=f[right];hash.put(in,hash.getOrDefault(in,0)+1);//進窗口while(hash.size()>2){//判斷int out=f[left];hash.put(out,hash.get(out)-1);//出窗口if(hash.get(out)==0){hash.remove(out);}left++;}ret=Math.max(ret,right-left+1);//更新長度}return ret;}

用數組來實現:?

    public int totalFruit(int[] f) {int n=f.length;int[] hash=new int[n+1];int ret=0;for(int left=0,right=0,kind=0;right<n;right++){int in=f[right];if(hash[in]==0){kind++;}hash[in]++;//進窗口while(kind>2){//判斷int out=f[left];hash[out]--;//出窗口if(hash[out]==0){kind--;}left++;}ret=Math.max(ret,right-left+1);//更新長度}return ret;}

?6.找出字符串中所有的異位字符串

題目鏈接:438. 找到字符串中所有字母異位詞 - 力扣(LeetCode)?

題目解析:再s字符串中找出p字符串中的所有異位字符串

異位字符串就是相同字符但是字符的順序不一樣組成的字符串,如abc、acb、bac、bca、cab和cba都是abc的異位字符串。?

解決思路:滑動窗口+哈希表

如何判斷兩個字符串互為異位字符串呢?

第一種方法:我們可以將兩個字符串按字典的順序進行排序,接著判斷這兩個字符串是否相同就行,如果相同,那么就是異位字符串,如果不同,則不是異位字符串。

第二種方法:借用兩個哈希表,hash1來存儲p字符串,hash2來存儲s字符串,最終判斷兩個哈希表是否相同,如果相同,那么互為異位字符串,如果不同,則不是異位字符串。?

?以下圖為例

我們在s中找p的異位字符串,我們使用暴力枚舉時,第一次枚舉時,?當right-left+1長度為p.length()時,第一次枚舉就結束了,如下圖

此時第一次枚舉就結束了,進行第二次枚舉,讓left++,同時讓right返回到left的所處的位置

進行第二次枚舉時,right繼續走向right-left+1=p.length()的位置,此時發現right依然會進過之前的字符b和字符a

所以,每一次進行新的枚舉,沒必要讓right回到left的位置,這樣left和right都是同向雙指針,這時,我們就可以用滑動窗口來解決問題。

?進窗口:當right-left+1<=s.length時,hash2[in]++

?判斷+出窗口

? ? ? ? 如果right-left+1>p.length(),就出窗口,讓hash2[out]--,同時讓left++

更新結果

? ? ? ? 要判斷是異位字符串在更新結果

代碼實現

//時間復雜度:O(n+m)
//空間復雜度:O(n+m)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];for(char ch:p){hash1[ch-'a']++;}for(int left=0,right=0;right<s.length;right++){char in=s[right];hash2[in-'a']++;//進窗口if(right-left+1>p.length){//判斷char out=s[left];hash2[out-'a']--;//出窗口left++;}//更新結果if(right-left+1==p.length){//判斷是否互為異位字符串boolean flag=true;for(int i=0;i<26;i++){if(hash1[i]!=hash2[i]){flag=false;}}if(flag==true)  ret.add(left);//更新結果}}return ret;}

進一步優化,此時我們可以在更新結果那里優化一下,因為在更新結果那里我們需要遍歷兩個哈希表,時間復雜度還是太大了,我們可以通過一個變量count統計窗口中的有效字符個數。

下圖解釋了什么是有效字符,一次類推?

前面我們用hash1統計了字符串p中的情況,用hash2統計了字符串s中的情況。

進窗口之后,我們對hash1[in]和hash2[in]進行比較,如果hash2[in]小于等于hash1[in],那么此時就可以認為該字符是一個有效字符,讓count++

出窗口之前,我們對hash1[out]和hash2[out]進行比較,如果hash2[out]小于等于hash[out],此時就可以認為出去的字符是一個有效字符,讓count--

最終在更新結果的時候,我們只要判斷count是否等于p.length,如果等于p.length,就更新結果,如果不等于p.length,就不更新結果。

代碼實現

       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];for(char ch:p){hash1[ch-'a']++;}for(int left=0,right=0,count=0;right<s.length;right++){char in=s[right];hash2[in-'a']++;//進窗口if(hash2[in-'a']<=hash1[in-'a']) count++;//更新有效字符個數if(right-left+1>p.length){//判斷char out=s[left];if(hash2[out-'a']<=hash1[out-'a']) count--;//更新有效字符個數hash2[out-'a']--;//出窗口left++;}//更新結果if(count==p.length) ret.add(left);}return ret;}

7.串聯所有單詞的子串?

題目鏈接:30. 串聯所有單詞的子串 - 力扣(LeetCode)?

?

我們如果將words的每一個字符串看成一個整體,在以這個整體為單位去在s中找串聯所有單詞的子串,這時就跟找異位字符串差不多了。如下圖

?

?這道題的思路和第6題的解題思路差不多,這里講不同點,假設words數組字符串的長度為m,數組的長度為len

1.right和left指針的位移

? ? ? ? right和left一次位移的長度為m

2.hash表的不同

? ? ? ? 這里的哈希表存的是字符串的種類和數量,即Hash<String,Integer>

3.進行滑動窗口的次數

? ? ? ? 次數為m次

這里對不同點3進行解釋

?

?代碼實現:

    public List<Integer> findSubstring(String s, String[] words) {Map<String,Integer> hash1=new HashMap<String,Integer>();//存儲wordsList<Integer> ret=new ArrayList<Integer>();for(String str:words){hash1.put(str,hash1.getOrDefault(str,0)+1);}int len=words[0].length(), m=words.length;for(int i=0;i<len;i++){//執行滑動窗口Map<String,Integer> hash2=new HashMap<String,Integer>();//存儲sfor(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++;//判斷+出窗口while(right-left+1>m*len){String out=s.substring(left,left+len);if(hash2.get(out)<=hash1.getOrDefault(out,0)) count--;hash2.put(out,hash2.getOrDefault(out,0)-1);left+=len;}//更新結果if(count==m) ret.add(left);}}return ret;}

8.最小覆蓋子串?

題目鏈接:76. 最小覆蓋子串 - 力扣(LeetCode)?

?

題目分析:我們需要再字符串s中找一個子串,在這個子串中的字符種類,需要包含字符串t中所有字符類型,如果t中有了重復的字符,那么從s中找的子串的該字符的數量必須大于等于t中的重復字符的數量。

比如t為aba,那么在s中找的子串中,字符a的數量是不能小于t中a的字符數量。?

解題思路:

首先,我們還是想到暴力枚舉+hash表,我們將字符串中s的字符都枚舉一遍,在枚舉的過程中,如果遇到符合題目要求的子串,此時,就更新結果,接著立刻換一個字符進行新的枚舉,以此類推下去。

優化思路:滑動窗口

如下圖?

?

此時,我們需要讓left往后移動一步,當left++之后,left和right之間就會出現兩種情況。

第一種情況:

如果left++之后,left和right之間的字符種類沒有發生變化,當我們讓right回到left的位置,進行新的枚舉時,right還是會回到原來的位置。如下圖?

?

第二種情況:?

如果left++之后,left和right之間的字符種類發生變化,當我們讓right回到left的位置時,進行新的枚舉,為了找到新的符合題目要求的子串,此時right肯定時跑到原來位置的后面。如下圖:?

?

所以,我們發現沒必要每次都要將right返回到原來left的位置,我們只要根據每次left移動后的情況,根據情況來讓right不動或者往后移動。?

此時,發現left和right都是同向雙指針,此時就可以使用滑動窗口。?

在使用滑動窗口前,我們要用到兩個哈希表,一個用來存儲s字符串的情況,另一個用來存儲t字符串的情況。?

?進窗口:hash2[in]++

?判斷+更新結果+出窗口:

? ? ? ? 判斷:在s中找的子串是否符合題目要求,也就是hash2與hash1對應字符的數量是否一?樣

? ? ? ? 跟新結果:由于我們這里找到一個符合題目要求的子串就要跟新結果,所以此處的跟新結果實在出窗口之前

? ? ? ? 出窗口:hash2[out]--

在進一步優化:更新結果

在更新結果那里,我們需要遍歷兩個哈希表來判斷找的子串是否符合題目要求,每個哈希表都要遍歷一遍,時間復雜度還是太大了,此時,我們可以通過count變量來統計hash1和hash2中完全相同的字符數量。?

這里的完全相同是指數量和種類都相同。?

在進窗口之后,如果hash2[in]==hash1[in],那么,我們認為在in在hash1和hash2中是完全相同的字符,則讓count++

出窗口之前,如果如果hash2[in]==hash1[in],那么,我們認為在in在hash1和hash2中是完全相同的字符,則讓count--?

此時判斷條件就變為count==hash1.size().

代碼實現:

    public String minWindow(String ss, String tt) {char[] s=ss.toCharArray();char[] t=tt.toCharArray();int[] hash1=new int[128];//存儲tint[] hash2=new int[128];//存儲s;int kinds=0;//記錄t中有效字符的種類for(char ch:t){if(hash1[ch]==0) kinds++;hash1[ch]++;}int minlen=Integer.MAX_VALUE, begin=-1;for(int left=0,right=0,count=0;right<s.length;right++){//進窗口char in=s[right];hash2[in]++;if(hash2[in]==hash1[in]) count++;//判斷+更新+出窗口while(kinds==count){//更新結果if(right-left+1<minlen){minlen=right-left+1;begin=left;}//出窗口char out=s[left];if(hash2[out]==hash1[out]) count--;hash2[out]--;//出窗口left++;//維護窗口}}if(begin==-1) return new String();else return ss.substring(begin,begin+minlen);}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62803.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62803.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62803.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# 中的Task

文章目錄 前言一、Task 的基本概念二、創建 Task使用異步方法使用 Task.Run 方法 三、等待 Task 完成使用 await 關鍵字使用 Task.Wait 方法 四、處理 Task 的異常使用 try-catch 塊使用 Task.Exception 屬性 五、Task 的延續使用 ContinueWith 方法使用 await 關鍵字和異步方法…

【AIGC】如何高效使用ChatGPT挖掘AI最大潛能?26個Prompt提問秘訣幫你提升300%效率的!

還記得第一次使用ChatGPT時&#xff0c;那種既興奮又困惑的心情嗎&#xff1f;我是從一個對AI一知半解的普通用戶&#xff0c;逐步成長為現在的“ChatGPT大神”。這一過程并非一蹴而就&#xff0c;而是通過不斷的探索和實踐&#xff0c;掌握了一系列高效使用的技巧。今天&#…

浩辰CAD教程004:柱梁板

文章目錄 柱梁板標準柱角柱構造柱柱齊墻邊繪制梁繪制樓板 柱梁板 標準柱 繪制標準柱&#xff1a; ①&#xff1a;點選插入柱子②&#xff1a;沿著一根軸線布置柱子③&#xff1a;指定的矩形區域內的軸線交點插入柱子 替換現有柱子&#xff1a;選擇替換之后的柱子形狀&#x…

UNIX數據恢復—UNIX系統常見故障問題和數據恢復方案

UNIX系統常見故障表現&#xff1a; 1、存儲結構出錯&#xff1b; 2、數據刪除&#xff1b; 3、文件系統格式化&#xff1b; 4、其他原因數據丟失。 UNIX系統常見故障解決方案&#xff1a; 1、檢測UNIX系統故障涉及的設備是否存在硬件故障&#xff0c;如果存在硬件故障&#xf…

橋接模式的理解和實踐

橋接模式&#xff08;Bridge Pattern&#xff09;&#xff0c;又稱橋梁模式&#xff0c;是一種結構型設計模式。它的核心思想是將抽象部分與實現部分分離&#xff0c;使它們可以獨立地進行變化&#xff0c;從而提高系統的靈活性和可擴展性。本文將詳細介紹橋接模式的概念、原理…

HTML綜合

一.HTML的初始結構 <!DOCTYPE html> <html lang"en"><head><!-- 設置文本字符 --><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- 設置網頁…

二維碼數據集,使用yolov,voc,coco標注,3044張各種二維碼原始圖片(未圖像增強)

二維碼數據集&#xff0c;使用yolov&#xff0c;voc&#xff0c;coco標注&#xff0c;3044張各種二維碼原始圖片&#xff08;未圖像增強&#xff09; 數據集分割 訓練組70&#xff05; 2132圖片 有效集20&#xff05; 607圖片 測試集10&#xff05; 305圖…

Python爬蟲技術的最新發展

在互聯網的海洋中&#xff0c;數據就像是一顆顆珍珠&#xff0c;而爬蟲技術就是我們手中的潛水艇。2024年&#xff0c;爬蟲技術有了哪些新花樣&#xff1f;讓我們一起潛入這個話題&#xff0c;看看最新的發展和趨勢。 1. 異步爬蟲&#xff1a;速度與激情 隨著現代Web應用的復…

用豆包MarsCode IDE,從0到1畫出精美數據大屏!

豆包MarsCode IDE 是一個云端 AI IDE 平臺&#xff0c;通過內置的 AI 編程助手&#xff0c;開箱即用的開發環境&#xff0c;可以幫助開發者更專注于各類項目的開發。 作為一名前端開發工程師&#xff0c;今天想嘗試利用豆包MarsCode IDE&#xff0c;選擇 Vue Echarts 創建一個…

游戲引擎學習第42天

倉庫: https://gitee.com/mrxiao_com/2d_game 簡介 目前我們正在研究的內容是如何構建一個基本的游戲引擎。我們將深入了解游戲開發的每一個環節&#xff0c;從最基礎的技術實現到高級的游戲編程。 角色移動代碼 我們主要討論的是角色的移動代碼。我一直希望能夠使用一些基…

Redis是什么?Redis和MongoDB的區別在那里?

Redis介紹 Redis&#xff08;Remote Dictionary Server&#xff09;是一個開源的、基于內存的數據結構存儲系統&#xff0c;它可以用作數據庫、緩存和消息中間件。以下是關于Redis的詳細介紹&#xff1a; 一、數據結構支持 字符串&#xff08;String&#xff09; 這是Redis最…

計算機網絡中的三大交換技術詳解與實現

目錄 計算機網絡中的三大交換技術詳解與實現1. 計算機網絡中的交換技術概述1.1 交換技術的意義1.2 三大交換技術簡介 2. 電路交換技術2.1 理論介紹2.2 Python實現及代碼詳解2.3 案例分析 3. 分組交換技術3.1 理論介紹3.2 Python實現及代碼詳解3.3 案例分析 4. 報文交換技術4.1 …

[Python] 操作redis使用pipeline保證原子性

1. pipeline介紹 在Python中使用Redis的Pipeline可以使多個Redis命令在一個請求中批量執行&#xff0c;從而提高效率。redis-py庫提供了對Redis Pipeline的支持&#xff0c;下面是一個基本的例子&#xff1a; 首先&#xff0c;確保你已安裝了redis庫&#xff1a; pip instal…

Bug 解決 無法正常登錄或獲取不到用戶信息

目錄 1、跨域問題 2、后端代碼問題 3、前端代碼問題 我相信登錄這個功能是很多人做項目時候遇到第一個檻&#xff01; **看起來好像很簡單的登錄功能&#xff0c;實際上還是有點坑的&#xff0c;比如明明賬號密碼都填寫正確了&#xff0c;**為什么登錄后請求接口又說我沒登…

論文翻譯 | ChunkRAG: Novel LLM-Chunk Filtering Method for RAG Systems

摘要 使用大型語言模型&#xff08;LLM&#xff09;的檢索-增強生成&#xff08;RAG&#xff09;系統經常由于檢索不相關或松散相關的信息而生成不準確的響應。現有的在文檔級別操作的方法無法有效地過濾掉此類內容。我們提出了LLM驅動的塊過濾&#xff0c;ChunkRAG&#xff0…

Maven(生命周期、POM、模塊化、聚合、依賴管理)詳解

Maven構建項目的生命周期 在Maven出現之前&#xff0c;項目構建的生命周期就已經存在&#xff0c;軟件開發人員每天都在對項目進行清理&#xff0c;編譯&#xff0c;測試&#xff0c;部署等工作&#xff0c;這個過程就是項目構建的生命周期。雖然大家都在不停的做構建工作&…

jenkins harbor安裝

Harbor是一個企業級Docker鏡像倉庫?。 文章目錄 1. 什么是Docker私有倉庫2. Docker有哪些私有倉庫3. Harbor簡介4. Harbor安裝 1. 什么是Docker私有倉庫 Docker私有倉庫是用于存儲和管理Docker鏡像的私有存儲庫。Docker默認會有一個公共的倉庫Docker Hub&#xff0c;而與Dock…

【Python網絡爬蟲筆記】10- os庫存儲爬取數據

os庫的作用 操作系統交互&#xff1a;os庫提供了一種使用Python與操作系統進行交互的方式。使用os庫來創建用于存儲爬取數據的文件夾&#xff0c;或者獲取當前工作目錄的路徑&#xff0c;以便將爬取的數據存儲在合適的位置。環境變量操作&#xff1a;可以讀取和設置環境變量。在…

微信小程序從后端獲取的圖片,展示的時候上下沒有完全拼接,有縫隙【已解決】

文章目錄 1、index.wxml2、index.js3、detail.detail為什么 .rich-text-style 樣式可以生效&#xff1f;1. <rich-text> 組件的特殊性2. 類選擇器的作用范圍3. 樣式優先級4. line-height: 0 的作用5. 為什么直接使用 rich-text 選擇器無效&#xff1f; 總結 上下兩張圖片…

Linux-apache虛擬主機配置筆記

一、 安裝apache 有需要的話&#xff0c;可以去查看具體的apache的安裝apache安裝https://blog.csdn.net/m0_68472908/article/details/139348739?spm1001.2014.3001.5501 都可以使用本地yum源搭建本地yum源搭建https://blog.csdn.net/m0_68472908/article/details/14385692…