暑期算法訓練.4

目錄

15.力扣 904.水果成籃

15.1 題目解析:

15.2 算法思路:

15.2.1 暴力解法:

15.2.1 滑動窗口

15.3代碼演示:

15.4 總結反思:

16 力扣 438.找出字符串中所有字母的異位詞

16.1 題目解析:

16.2算法思路:

16.3 代碼實現:

?編輯

16.4 總結反思:

17 力扣 30.串聯所有單詞的子串

17.1 題目解析:

17.2 算法思路:

17.3 代碼演示:

?編輯

17.4 總結反思:

18. 力扣 76。最小覆蓋子串

18.1 題目解析:

18.2 算法思路:

18.2.1 暴力枚舉+哈希表

?編輯18.2.2 優化解法:

18.3 代碼演示:

?18.4 總結反思:

19 力扣 704.二分查找

19.1?題目解析:

?19.2 算法思路:

19.3 代碼演示:

?編輯

19.4 總結反思:

?

?


15.力扣 904.水果成籃

15.1 題目解析:

要是單單的看這道題目,確實挺難理解的。不過大家仔細的閱讀一下,基本可以理解意思,我把題目給翻譯了一下:大體的意思可以翻譯為找出一個最長的子數組的長度,子數組中不超過兩種類型的水果。?最后返回收集到的最大的水果的數目。

15.2 算法思路:

15.2.1 暴力解法:

解法一就是暴力解法,就是找出子數組,找出其中最長的即可,其中要用到哈希表來存儲水果出現的種類。(若表中水果超過了2種,則直接不用往里面放了)。

15.2.1 滑動窗口

最主要的還是第二種解法。不過在直到用到滑動窗口做之前,還需要直到為什么要用到滑動窗口?

那么大家看著這個圖,我來給大家分析一下。圖中left與right之間是kinds=2,但是如果說left往右挪動一個數字,挪到了新的left的位置,那么請問,kinds的大小會怎么變呢?

1.kinds不變,因為若left與right中間恰好有一種水果有兩個,這不正好抵消了嗎?那么此時right也不變。

2.kinds變小,此時說明,恰好把那種水果給挪走了。那么此時right右移(增加水果的種類)。

所以說,right從圖中的位置開始移動left也一直向右邊移動。所以,他們倆是同向的。既然是同向的,那么也就是會用到滑動窗口。并且這個題也涉及到了子數組。

?所以:

1.left,right都是從0開始的。

2.進窗口:這個就是hash[fruits[right]]++.

3.那么判斷出窗口的標準就是hash的大小大于2.出窗口,出了窗口之后,hash[fruits[left]]--。減完后,還得加一步判斷,如果說你的這個hash[fruits[left]]==0,那么這種水果的數量為0,則要把這種水果從哈希表中給踢出去(種類減一)。之后left才加加。(順序別搞錯了)。因為你left先加加的話,會導致這個位置的水果數量還沒判斷呢。

15.3代碼演示:

1.帶容器:若用hash表的話,你得定義兩個int,即hash<int,int>,第一個int表示哪種水果,第二個int表示這種水果有幾個。并且踢出水果要用hash.erase();

?
//使用哈希表(容器)
int totalFruit(vector<int>& fruits) {unordered_map<int, int> hash; //統計窗?內出現了多少種?果int n = fruits.size();int ret = 0;int left = 0;int right = 0;int kind = 0;for (; right < n; right++){if (hash[fruits[right]] == 0) kind++;//若這種水果的數量為0,則要加入這種水果hash[fruits[right]]++;//增加這種水果的數量while (hash.size() > 2)//出窗口{hash[fruits[left]]--;if (hash[fruits[left]] == 0)hash.erase(fruits[left]);//將這種水果刪除left++;}ret = max(ret, right - left + 1);}return ret;
}
int main()
{vector<int> fruits = { 3,3,3,1,2,1,1,2,3,3,4 };cout << totalFruit(fruits) << endl;return 0;
}?

但是呢,帶容器的嘛,肯定時間復雜度不夠好。所以下面還有一個利用數組來模擬哈希表的寫法:

2.用數組代替哈希,得判斷一下,若數組中這種水果數量為0,則數組中還沒有這種水果,就要++kinds,踢出元素的時候,也是這種水果的數量減到0的時候,才踢出去。

//使用數組模擬哈希表
int totalFruit(vector<int>& fruits) {int hash[100000] = { 0 };//定義哈希數組存放水果int n = fruits.size();int ret = 0;int left = 0;int right = 0;int kind = 0;for (; right < n; right++){if (hash[fruits[right]] == 0) kind++;//若這種水果的數量為0,則要加入這種水果hash[fruits[right]]++;//增加這種水果的數量while (kind > 2)//出窗口{hash[fruits[left]]--;if (hash[fruits[left]] == 0) kind--;//將這種水果刪除left++;}ret = max(ret, right - left + 1);}return ret;
}
int main()
{vector<int> fruits = { 3,3,3,1,2,1,1,2,3,3,4 };cout << totalFruit(fruits) << endl;return 0;
}

15.4 總結反思:

總結下來還是滑動窗口的那些做題方法。

16 力扣 438.找出字符串中所有字母的異位詞

16.1 題目解析:

大家仔細閱讀題目,就可知異位詞是什么。例如:abc,那么abc,acb,bac,bca,cab,cba。均為abc的異位詞。

16.2算法思路:

這個的算法思路比較復雜,細節也比較多。

?

?

以上就是本題算法的所有細節與思路了,還是挺多的。關鍵是不好想。

16.3 代碼實現:

//找出字符串中所有字母的異位詞
vector<int> findAnagrams(string s, string p) {vector<int> ret;int hash1[26] = { 0 };//這個數組存儲p中的字符的個數for (auto& e : p) hash1[e - 'a']++;int hash2[26] = { 0 };//這個數組存儲s中的字符個數for (int left = 0, right = 0, count = 0; right < s.size(); right++){char in = s[right];//定義一個進來的變量hash2[in - 'a']++;if (hash2[in - 'a'] <= hash1[in - 'a'])  count++;//count的作用是起到一個統計有效字符的作用if (right - left + 1 > p.size())//此時出窗口的判斷條件{char out = s[left];if (hash2[out - 'a'] <= hash1[out - 'a'])  count--;hash2[out - 'a']--;//這個是在判斷count后才減的,因為你要是先減完了,那怎么能判斷這個位置的字符的個數呢?left++;}if (count == p.size()) ret.push_back(left);}return ret;
}
int main()
{vector<int> outcome;string s("cbaebabacd");string p("abc");outcome = findAnagrams(s, p);for (auto& e : outcome){cout << e << "";}cout << endl;return 0;
}

16.4 總結反思:

本題還是挺有挑戰性的。即使你的思路想出來了,但是如果說你的代碼能力不夠強,也還是寫不出這樣的代碼的。

17 力扣 30.串聯所有單詞的子串

17.1 題目解析:

大家一看到這是個困難題目,好家伙一下子,全蔫了。沒事,不要緊。這道題,你仔細的閱讀一下,是不是跟上一題尋找異位詞差不多,只不過這里的字符變成了字符串。所以本題的解答思路就是,將這些字符串看成字符進行解答。但是細節上呢,可能有些不同。接下來在算法思路里面講解:

17.2 算法思路:

?

本道題目與上一道題目的算法思路幾乎一模一樣,就是一些細節不一樣而已。

17.3 代碼演示:

//串聯所有單詞的子串
vector<int> findSubstring(string s, vector<string>& words) {vector<int> ret;unordered_map<string, int> hash1;//記錄一下words只出現的單詞的頻率for (auto& e : words) hash1[e]++;int len = words[0].size();for (int i = 0; i < len; i++){unordered_map<string, int> hash2;for (int left = i, right = i, count = 0; right + len <= s.size(); right += len)//注意這個地方是right+len<=s.size(),否則到了最后就會越界。后面是加len{string in = s.substr(right, len);hash2[in]++;if (hash2[in] <= hash1[in]) count++;while (right - left + 1 > len * (words.size()))//這個地方只需要看right-left+1比words中的長度長即可證明該出窗口了{string out = s.substr(left, len);//這個只是一個下標if (hash2[out] <= hash1[out])  count--;//是有效字符hash2[out]--;left += len;}if (count == words.size())  ret.push_back(left);}}return ret;
}
int main()
{string s("barfoothefoobarman");vector<string> words = { "foo","bar" };vector<int> outcome = findSubstring(s, words);for (auto& e : outcome){cout << e << "";}cout << endl;return 0;
}

注意是加len。

17.4 總結反思:

還是得先真正的搞懂一道題目之后,才可以對類似的題目得心應手。

18. 力扣 76。最小覆蓋子串

18.1 題目解析:

題目很短,也很好理解,關鍵就是在于怎么去找出很好的方法去解開這道題。

18.2 算法思路:

18.2.1 暴力枚舉+哈希表

18.2.2 優化解法:

以上便是這道題的全部思路以及細節?,其實還是挺復雜的。

另外還有一些需要注意:

1.能用數組的就用數組,因為數組非常的快(比容器要快)

2.一般,當只有字符的時候,可以用數組,因為字符容易找到下標,就是存儲的位置,且你要是hash[26],那得減去'a',。因為只有26個位置。但要是128的話,就沒必要減了,因為ascii碼表也才127個值

3.字符串只能使用容器(哈希表),因為用數組,無法找到可以存儲的位置。且容器還得有string,int。即unordered_map<string,int>才可以。

18.3 代碼演示:

//最小覆蓋子串
string minWindow(string s, string t) {int hash1[128] = { 0 };int kinds = 0;//統計一下t中的字符的種類有多少for (auto& e : t){if (hash1[e] == 0) kinds++;//如果說這個hash1[e]==0的話,說明暫時沒有這個種類,則需要加上這個種類hash1[e]++;//統計t中的各個字符出現的次數}int hash2[128] = { 0 };int minlen = INT_MAX;int begin = -1;//這個是作為返回字符串的起始位置的beginfor (int left = 0, right = 0, count = 0; right < s.size(); right++){char in = s[right];hash2[in]++;//進窗口if (hash2[in] == hash1[in])  count++;while (count == kinds){if (right - left + 1 < minlen) //這個就是取出最小的長度的符合要求的字符串{minlen = right - left + 1;begin = left;//作為那個字符串的起始位置,因為后面要使用substr}char out = s[left];if (hash2[out] == hash1[out])  count--;hash2[out]--;//判斷完了之后,別忘了將這個字符給題出,因為雖然說left++了,但這個畢竟是另開了一個數組,所以這個數組里面的變化也得跟著原字符串的變化,原字符串++了,那么這個數組只能踢字符了left++;}}if (begin == -1) return "";else return s.substr(begin, minlen);//這個是選取字符串,所以只能在已有的字符串中選取
}
int main()
{string s("ADOBECODEBANC");string t("ABC");string outcome = minWindow(s, t);cout << outcome << endl;return 0;
}

?18.4 總結反思:

處理好一些細節,就可以把一道題做的很好。

19 力扣 704.二分查找

在介紹這道題目之前,先來介紹一下二分算法。

二分算法,可能剛開始使用,會覺得有點難。但是你要是洞悉了二分算法的原理,其實挺簡單的。

且這個算法不管數組有序還是沒序。你只要找到規律之后,都可以使用二分算法的。

19.1?題目解析:

這道題算是我從寫博客以來最簡單的。暴力可以解決,但今天咱們講二分算法。

?19.2 算法思路:

?

19.3 代碼演示:

int search(vector<int>& nums, int target) {int left = 0; int right = nums.size() - 1;while (left <= right)//注意這個是進入循環條件{int mid = left + (right - left) / 2;if (nums[mid] < target) left = mid + 1;else if (nums[mid] > target)  right = mid - 1;else return mid;}return -1;
}
int main()
{vector<int> nums = { -1,0,3,5,9,12 };int target = 9;cout << search(nums, target) << endl;return 0;
}

這個求中間點一般是用到(right-left)/2+left。因為如果使用(left+right)/2,left+right會有溢出的風險。

19.4 總結反思:

這只是二分算法的一道開胃小菜。后面還有更大的禮物呢。?

?

?

?

?

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

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

相關文章

關于個人博客系統的測試報告

1&#xff09;項目背景2&#xff09;項目功能介紹 登陸寫博客/編輯已存在博客刪除博客注銷 2&#xff09;基于項目功能設計相關測試用例3&#xff09;基于測試用例編寫自動化測試 準備工作登陸界面相關博客首頁相關博客詳情頁相關編輯博客相關刪除博客相關注銷相關 4&#xff0…

Spring Boot 與微服務詳細總結

一、Spring Boot 核心概述 Spring Boot 是簡化 Spring 應用開發的框架&#xff0c;作為 Spring 技術棧的整合方案和 J2EE 開發的一站式解決方案&#xff0c;其核心優勢體現在&#xff1a; 快速創建獨立運行的 Spring 項目&#xff0c;輕松集成主流框架內置 Servlet 容器&…

輕松上手:從零開始啟動第一個 Solana 測試節點

嗨&#xff0c;各位技術愛好者們&#xff01; 大家是否對 Solana 的“光速”交易處理能力感到好奇&#xff1f;或者你是一名開發者&#xff0c;正準備在 Solana 上構建下一個殺手級 dApp&#xff1f;無論大家是出于學習目的還是實際開發需求&#xff0c;親手運行一個 Solana 節…

Gerrit workflow

提交代碼 每次提交代碼前&#xff0c;先執行 git pull --rebase &#xff0c;確保已經合并天上代碼&#xff0c;解決沖突 git add git commit -m git push origin HEAD:refs/for/{BRANCH_NAME} 可考慮設置 alias 方式&#xff0c;參考下文 CR-2 情況處理(verify-1情況一樣處理…

量化交易如何查詢CFD指數實時行情

CFD即所謂的差價合約&#xff0c;是投資者在不擁有實際資產的情況下&#xff0c;交易金融市場的一種方式。最近筆者研究這一塊比較多&#xff0c;但查遍整個中文互聯網卻很少找到關于CFD實時行情的查詢教程。因此有了這篇文章。以下我將通過一個簡單的Python代碼示例&#xff0…

sql練習二

首先&#xff0c;建表。創建學生表和score表接著導入創建好基礎信息就可以開始做了。3、分別查詢student表和score表的所有記錄4、查詢student表的第2條到第5條記錄5、從student表中查詢計算機系和英語系的學生的信息6、從student表中查詢年齡小于22歲的學生信息7、從student表…

windows11下基于docker單機部署ceph集群

windows下基于docker單機部署ceph集群 創建ceph專用網絡 docker network create --driver bridge --subnet 172.20.0.0/16 ceph-network查看是否創建成功&#xff08;查看創建狀態&#xff09; docker network inspect ceph-network拉取鏡像&#xff1a;(鏡像源自行選擇) docke…

使用DataGrip連接安裝在Linux上的Redis

目錄 一、前言 二、開放防火墻端口 三、使用DataGrip連接安裝在Linux上的Redis 一、前言 在學習黑馬Redis從入門到實戰的視頻&#xff0c;完成了Redis在linux上的安裝配置之后&#xff0c;我們可以使用圖形化界面方便操作使用redis數據庫。在24年JavaWebAI學習時連接MySQL數…

MySQL的union、union all導致排序失效

今天練習SQL&#xff0c;使用union all 連接各個查詢導致我的各個查詢排序失效&#xff0c;最后發現使用union all后會忽略各個模塊的order by&#xff0c;只有最外層的order by才會生效原SQL如下&#xff1a;( selectexam_id tid,count(distinct uid) uv, count(uid) pv frome…

LVS 集群技術實踐:NAT 與 DR 模式的配置與對比

1 實驗環境規劃 實驗目標是搭建一個負載均衡集群&#xff0c;通過 LVS 調度器將流量分發到兩臺真實服務器&#xff08;RS1 和 RS2&#xff09;。2.網絡配置3 實驗步驟關閉防火墻和 SELinux安裝 HTTP 服務&#xff08;在 RS21和 RS2 上&#xff09;&#xff1a;sudo systemctl s…

YOLOv8中添加SENet注意力機制

注意力機制(Attention Mechanism)是深度學習中的一種方法,在圖像處理領域,尤其是在卷積神經網絡(CNN)和視覺Transformer等架構中。圖像數據具有局部相關性,注意力機制可以幫助模型聚焦于圖像中更重要的區域,從而提升處理效果。 SENet(Squeeze-and-Excitation Network)…

SpringBoot五分鐘快速入門指南

使用 Spring Boot 構建應用 本指南提供了關于Spring Boot如何幫助您加速應用開發的一些示例。隨著您閱讀更多 Spring 入門指南,您將看到 Spring Boot 的更多用例。本指南旨在讓您快速了解 Spring Boot。如果您想創建自己的基于 Spring Boot 的項目,請訪問 Spring Initializr…

docker,防火墻關閉后,未重啟docker,導致端口映射失敗

首先&#xff0c;看這篇文章前&#xff0c;建議先把網上其他的文章說的方法嘗試一遍&#xff01;&#xff01;&#xff01; 1. 現象 docker啟動某一個容器&#xff0c;然后映射端口時顯示失敗2. 解決 把網上的方法嘗試一遍之后&#xff0c;最后發現是防火墻的問題&#xff01;&…

事務處理與AOP(web后端筆記第四期)

p.s.這是萌新自己自學總結的筆記&#xff0c;如果想學習得更透徹的話還是請去看大佬的講解 目錄事務spring事物管理事物屬性--回滾事物屬性--傳播行為(propagation)AOP一些核心概念通知類型通知的執行順序切入點表達式executionannotation連接點事務 事物是一組操作的集合&…

第36周———— RNN實現阿爾茨海默病診斷

目錄 前言 1.檢查GPU 2.查看數據 3.劃分數據集 4.創建模型與編譯訓練 ????5.編譯及訓練模型 6.結果可視化 7.模型預測 8.總結&#xff1a; 前言 &#x1f368; 本文為&#x1f517;365天深度學習訓練營中的學習記錄博客 &#x1f356; 原作者&#xff1a;K同學啊 1.檢查G…

equals和hashcode方法重寫

在 Java 中&#xff0c;當你需要基于對象的內容而非引用地址來判斷兩個對象是否相等時&#xff0c;就需要重寫equals和hashCode方法。以下是具體場景和實現原則&#xff1a;一、為什么需要同時重寫這兩個方法&#xff1f;equals方法&#xff1a;默認比較對象的內存地址&#xf…

Excel批量生成SQL語句 Excel批量生成SQL腳本 Excel拼接sql

Excel批量生成SQL語句 Excel批量生成SQL腳本 Excel拼接sql一、情境描述在Excel中有標準的格式化數據&#xff0c;如何快速導入到數據庫中呢&#xff1f;有些工具支持Excel導入的&#xff0c;則可以快速導入數據---例如Navicat&#xff1b;如果不支持呢&#xff0c;如果將Excel表…

金和OA C6 DelTemp.aspx 存在XML實體注入漏洞(CVE-2025-7523)

免責聲明 本文檔所述漏洞詳情及復現方法僅限用于合法授權的安全研究和學術教育用途。任何個人或組織不得利用本文內容從事未經許可的滲透測試、網絡攻擊或其他違法行為。 前言:我們建立了一個更多,更全的知識庫。每日追蹤最新的安全漏洞,追中25HW情報。 更多詳情: http…

Android性能優化之啟動優化

一、啟動性能瓶頸深度分析 1. 冷啟動階段耗時分布階段耗時占比關鍵阻塞點進程創建15%fork進程 加載ZygoteApplication初始化40%ContentProvider/庫初始化Activity創建30%布局inflate 視圖渲染首幀繪制15%VSync信號等待 GPU渲染2. 高頻性能問題 初始化風暴&#xff1a;多個庫…

中國優秀開源軟件及企業調研報告

中國優秀開源軟件及企業調研報告 引言 當前中國開源生態呈現蓬勃發展態勢&#xff0c;技術創新領域尤為活躍&#xff0c;其中人工智能大模型成為開源動作的核心聚焦方向。2025年上半年&#xff0c;國內AI領域開源生態迎來密集爆發&#xff0c;頭部科技企業相繼推出重要開源舉…