暑期算法訓練.5

目錄

20. 力扣 34.在排序數組中查找元素的第一個位置和最后一個位置

20.1 題目解析:

20.2 算法思路:

20.3 代碼演示:

?編輯

20.4 總結反思:

21.力扣 69.x的平方根?

21.1 題目解析:

21.2 算法思路:

21.3 代碼演示:

21.4 總結反思:

22. 力扣 35.搜索插入位置

22.1 題目解析:

22.2 算法思路:

22.3 代碼演示:

?編輯

22.4 總結反思:

23 力扣. 852 山脈數組的封頂索引

23.1 題目解析:

23.2 算法思路:

23.3 代碼演示:

23.4 總結反思:

24.力扣 162 尋找峰值:

24.1 題目解析:

?編輯?

24.2 算法思路:

24.3 代碼演示:

24.4 總結反思:

25.力扣 LCR 173 點名

25.1 題目解析:

25.2 算法思路:

25.3 代碼演示:

?編輯

25.4 總結反思:

26 力扣 153.尋找旋轉排序數組中的最小值

26.1 題目解析:

26.2 算法思路:

26.3 代碼演示:

?編輯

26.4 總結反思:

?

?

?

?

?


20. 力扣 34.在排序數組中查找元素的第一個位置和最后一個位置

20.1 題目解析:

題目很好理解,就是讓你找出目標值的開始以及結束的位置。不過這道題目要注意處理一下,空數組以及沒有結果的情況。

20.2 算法思路:

1.解法一就是暴力解法,就是遍歷一遍數組,然后找出區間即可。這個的時間復雜度肯定是O(N)

2.解法二是咱們今天重點講解的,就是用二分算法去解決這道題目。咱們直到,要想用二分算法,得先關注一下這道題目,得具有二段性才可以使用二分算法。?升不升序倒是無所謂。因為你只要發現了規律,均可以使用二分算法。

【1】求區間左端點

?

【2】求區間右端點

總結一下就是:

?

好了,這個題目的算法思路可算是寫明白了。

20.3 代碼演示:

vector<int> searchRange(vector<int>& nums, int target) {if (nums.size() == 0)  return { -1,-1 };//處理一下數組為空的情況int begin = 0;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 right = mid;}//判斷一下是否有結果,因為出了while循環后,left==rightif (nums[left] != target) return { -1,-1 };else begin = left;//這里寫begin的目的僅僅是為了將left給存起來left = 0; right = nums.size() - 1;//其實,left直接從左端點開始就可以了while (left < right){int mid = left + (right - left + 1) / 2;if (nums[mid] <= target) left = mid;else right = mid - 1;}return { begin,right };//此時不需要判斷是否有結果,因為只要有左端點,那么就一定有結果
}
int main()
{vector<int> nums = { 5,7,7,8,8,10 };int target = 8;vector<int> outcome = searchRange(nums, target);for (auto& e : outcome){cout << e << "";}cout << endl;return 0;
}

20.4 總結反思:

咱們來總結一下這類二分的模板:

?

不用死記硬背,只需要記住一點:就是若是下面出現了-1,那么上面mid給它加上1就可以了。

記住了求中點的方式,就可以推導出其他的了。

21.力扣 69.x的平方根?

21.1 題目解析:

21.2 算法思路:

暴力解法很簡單,就是遍歷一邊【0,x】內的數字i,若?i*i=x,直接返回x。若是i*i>x,則返回上一個數即可。

下面看解法二:

注意:尋找區間左端點,即找到大于等于目標值,說明右邊還有滿足條件的目標值(第一個滿足條件的元素)。

尋找區間右端點:即找到小于等于目標值,說明右邊不可能還有滿足條件的目標值。(最后一個滿足條件的元素)

所以說,為什么說這個尋找左端點是: <? ? ? ?>=.原理上將等于歸于右邊,是因為若mid位于兩個相等的值中間,此時不是最終結果。但你也可以想成,就是找左端點,右邊肯定還有值。所以找右端點:左邊還有值,就是<=? ? ? ?>

所以本題是尋找k*k<=x,尋找右端點模板。

21.3 代碼演示:

int mySqrt(int x) {if (x < 1)  return 0;//處理邊界情況int left = 0;long long right = x;while (left < right){long long mid = left + (right - left + 1) / 2;//long long 防止溢出if (mid * mid <= x)  left = mid;else right = mid - 1;}return left;
}
int main()
{int x = 4;cout << mySqrt(x) << endl;return 0;
}

21.4 總結反思:

這個起始也就是一種二分算法的模板而已。

22. 力扣 35.搜索插入位置

22.1 題目解析:

注意關鍵句子:有序數組找到一個值。

22.2 算法思路:

1.找到了:直接返回下標即可。

2.若是沒找到,就第一次出現了比目標值大的那個數(那個數大于等于目標值target)。或者數組末尾。

這個mid(x)其實就是“那個數”,然后再繼續進行判斷即可。

22.3 代碼演示:

int searchInsert(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 right = mid;}if (nums[left] < target) return left + 1;//處理一下邊界的情況,就是插入到數組末尾return left;
}
int main()
{vector<int> nums = { 1,3,5,6 };int target = 5;cout << searchInsert(nums, target) << endl;return 0;
}

22.4 總結反思:

這道題目是用到了求左端點的模板。要注意分清楚,還是挺好抓住的。

23 力扣. 852 山脈數組的封頂索引

23.1 題目解析:

就是讓你找出山頂的索引。

23.2 算法思路:

就是找出最大的值唄。

1.暴力解法也好辦,即使先遍歷一遍數組,直至找到后一個數字比前一個數字小為止。返回那個數字的下標就可以了。

2.解法二就是二分查找算法:

那么這個時候:1.arr[mid]>arr[mid-1](說明要到右區間去找),left=mid

? ? ? ? ? ? ? ? ? ? ? ? ? 2.arr[mid]<arr[mid-1](說明要到左區間去找),即right=mid-1

mid位置呈現上升:那么接下來要在[mid+1,right]區間內搜索山峰。

mid位置呈現下降趨勢,在[left,mid-1]區間內搜索山峰。

mid位置就是山峰,那么直接返回即可。

23.3 代碼演示:

int peakIndexInMountainArray(vector<int>& arr) {int left = 0; int right = arr.size();while (left < right){int mid = left + (right - left + 1) / 2;if (arr[mid] > arr[mid - 1])  left = mid;else right = mid - 1;}return left;
}
int main()
{vector<int> arr = { 0,1,0 };cout << peakIndexInMountainArray(arr) << endl;return 0;
}

23.4 總結反思:

這道題目就不可以傻乎乎的再硬用了,需要分析一下為什么使用二分算法了。

24.力扣 162 尋找峰值:

24.1 題目解析:

?

上一道題目是只有一個峰,但這個是有好多個峰,但是只返回任意一個峰即可。

并且題目中要求左,右,都可以是無窮小。

24.2 算法思路:

暴力解法:就是從第一個位置開始,一直向后走,分情況討論:

?

1.一開始就下降。2,上升著突然就下降了。3? 一直向上走到最后一個位置。

2.二分算法:

?

這個mid應該就是隨機選取的地方,然后再由這個分析規律(一開始,mid可能不等于你要求的那個值,只要是一個隨機的值,但是循環完了,之后呢?left=right,此時的mid即為所求的值了。)

且上面所說的模板,若你right=mid-1,看到了減去一,那么在前面加上一就可以了。?

24.3 代碼演示:

?

int findPeakElement(vector<int>& nums) {int left = 0; int right = nums.size() - 1;while (left < right){int mid = left + (right - left) / 2;if (nums[mid] > nums[mid + 1]) right = mid;else left = mid + 1;}return left;
}int main()
{vector<int> nums = { 1,2,3,1 };cout << findPeakElement(nums) << endl;return 0;
}

24.4 總結反思:

這道題目也是考你靈活的運用二分模板。

25.力扣 LCR 173 點名

25.1 題目解析:

?這道題目就是讓你找出缺失的數字

25.2 算法思路:

其實這道題目解法有很多,但是咱們今天在這里只講二分算法:

這個3就是區間的左端點。

1.左區間:若nums[mid]==mid,則left=mid+1;

2.右區間:nums[mid]!=mid,則right=mid

細節問題:邊界:[0 ,1 ,2 ,3 ] 那么它缺的就是4.但是二分算法尋找的是右區間。但是這里沒有右區間。所以,若最后一個值與下標值相同,則為完全遞增數組,則返回left+1即可。

25.3 代碼演示:

//點名
int takeAttendance(vector<int>& records) {int left = 0; int right = records.size() - 1;while (left < right){int mid = left + (right - left) / 2;if (records[mid] == mid)  left = mid + 1;else right = mid;}if (left == records[left]) return left + 1;else return left;
}
int main()
{vector<int> records = { 0,1,2,3,5 };cout << takeAttendance(records) << endl;return 0;
}

25.4 總結反思:

這道題目也是一道令人有想法的二分算法。?

26 力扣 153.尋找旋轉排序數組中的最小值

26.1 題目解析:

這道題目是我做的二分算法題目里面最不好理解的,也是最不好想的。題目很簡單。咱們接下來看怎么做

26.2 算法思路:

咱們只講二分算法:

?

好,這個是以D點為參照點。那么以A點為參照點呢?

26.3 代碼演示:

以D點為參照點:

//尋找旋轉排序數組中的最小值
//以D點為參照點
int findMin(vector<int>& nums)
{int left = 0, right = nums.size() - 1;int x = nums[right]; // 標記?下最后?個位置的值(D點)while (left < right){int mid = left + (right - left) / 2;if (nums[mid] > x) left = mid + 1;else right = mid;}return nums[left];
}
int main()
{vector<int> nums1 = { 4,5,6,7,0,1,2 };vector<int> nums2 = { 3,4,5,1,2 };vector<int> nums3 = { 11,13,15,17 };cout << "nums1的最小值: " << findMin(nums1) << endl; // 輸出0cout << "nums2的最小值: " << findMin(nums2) << endl; // 輸出1cout << "nums3的最小值: " << findMin(nums3) << endl; // 輸出11return 0;
}

以A點為參照點:

//以A點為參照點
int findMin(vector<int>& nums) {int left = 0;                  // A點,左邊界int right = nums.size() - 1;// 數組未旋轉的情況(完全升序)if (nums[left] <= nums[right]) {return nums[left];}// 二分查找while (left < right) {int mid = left + (right - left) / 2;// 中間元素大于左邊界元素,說明左半部分有序,最小元素在右半部分if (nums[mid] > nums[left]) {left = mid;}// 中間元素小于左邊界元素,說明最小元素在左半部分(包括mid)else {right = mid;}}// 循環結束時left == right,此時下一個元素即為最小值return nums[left + 1];
}
int main()
{vector<int> nums1 = { 4,5,6,7,0,1,2 };vector<int> nums2 = { 3,4,5,1,2 };vector<int> nums3 = { 11,13,15,17 };cout << "nums1的最小值: " << findMin(nums1) << endl; // 輸出0cout << "nums2的最小值: " << findMin(nums2) << endl; // 輸出1cout << "nums3的最小值: " << findMin(nums3) << endl; // 輸出11return 0;
}

26.4 總結反思:

這道題目是今天最抽象的題目,大腳要好好的理解才可以。

本篇完......................?

?

?

?

?

?

?

?

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

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

相關文章

【HDLBits習題詳解 2】Circuit - Sequential Logic(5)Finite State Machines 更新中...

1. Fsm1&#xff08;Simple FSM 1 - asynchronous reset&#xff09;狀態機可分為兩類&#xff1a;&#xff08;1&#xff09;Mealy狀態機&#xff1a;輸出由當前狀態和輸入共同決定。輸入變化可能立即改變輸出。&#xff08;2&#xff09;Moore狀態機&#xff1a;輸出僅由當前…

多級緩存(億級流量緩存)

傳統緩存方案問題 多級緩存方案 流程 1.客戶端瀏覽器緩存頁面靜態資源; 2. 客戶端請求到Nginx反向代理;[一級緩存_瀏覽器緩存] 3.Nginx反向代理將請求分發到Nginx集群(OpenResty); 4.先重Nginx集群OpenResty中獲取Nginx本地緩存數據;[二級緩存_Nginx本地緩存] 5.若Nginx本地緩存…

淺談Rust語言特性

如大家所了解的&#xff0c;Rust是一種由Mozilla開發的系統編程語言&#xff0c;專注于內存安全、并發性和高性能&#xff0c;旨在替代C/C等傳統系統編程語言。Rust 有著非常優秀的特性&#xff0c;例如&#xff1a;可重用模塊 內存安全和保證&#xff08;安全的操作與不安全的…

React探索高性能Tree樹組件實現——react-window、react-vtree

&#x1f680; 簡介 在現代 Web 應用中&#xff0c;處理大量層級數據的樹形結構是一個常見挑戰。傳統的樹組件在面對成千上萬個節點時往往會出現性能瓶頸&#xff0c;導致頁面卡頓、內存占用過高等問題。本文將深入探討如何使用 react-window 和 react-vtree 構建高性能的虛擬…

C++ 中的默認構造函數:非必要,不提供

《More Effective C&#xff1a;35個改善編程與設計的有效方法》 讀書筆記&#xff1a;非必要不提供default constructor在 C 中&#xff0c;默認構造函數&#xff08;即無需任何參數即可調用的構造函數&#xff09;是對象“無中生有”的一種方式。它的核心作用是在沒有外部信息…

如何選擇低代碼開發平臺

選擇低代碼開發平臺需要考慮平臺的開發效率、靈活性和擴展能力、安全性和合規性、成本效益等關鍵因素。 具體來說&#xff0c;平臺的靈活性和擴展能力尤為重要&#xff0c;這決定了平臺是否能長期滿足企業日益增長的復雜需求。例如&#xff0c;企業在評估平臺時&#xff0c;應關…

電子數據取證領域的雙輪驅動——手工分析 vs 自動化分析

在你剛步入電子數據取證領域時&#xff0c;可能很快就注意到一個普遍現象&#xff1a;大多數取證分析師前期都花費大量時間在網上查閱博客、PDF、推文等信息&#xff0c;尋找證據線索的“藏身之處”——例如注冊表項、日志文件路徑、可疑文件命名模式或遠程登錄痕跡等。這種信息…

《Python 實時通信全解:掌握 WebSocket 技術與 HTTP 的本質區別》

??《Python 實時通信全解:掌握 WebSocket 技術與 HTTP 的本質區別》 引言:通信方式的演進與 Python 的角色 在數字化世界里,**“實時性”**已經成為構建高質量應用的核心訴求。從聊天工具到股票交易系統,再到物聯網設備管理——通信的即時響應能力直接決定用戶體驗。而…

GeoTools 自定義坐標系

前言在GIS開發中&#xff0c;坐標系統是重中之重&#xff0c;在接到任務時首先要確定的就是坐標系。大多數地圖庫或者互聯網地圖默認支持WGS84地理坐標系和Web墨卡托投影坐標系。而在我國要求使用自然資源數據使用2000國家大地坐標&#xff08;CGCS2000&#xff09;。1. 背景 經…

[特殊字符] Java反射從入門到飛升:手撕類結構,動態解析一切![特殊字符]

【&#x1f50d;震撼揭秘】 你是否曾想窺探Java類的內部結構&#xff1f;&#x1f914; 是否好奇Spring框架如何實現"萬物皆可注入"&#xff1f;? 本文將帶你從反射小白晉升為反射高手&#xff0c;用一行代碼透視任意類的構造方法、成員變量和私有方法&#xff01;&…

CMake與catkin_make的find_package()命令使用說明

在 CMake 中&#xff0c;find_package() 是一個核心函數&#xff0c;用于查找并加載外部依賴庫的配置。它的主要作用是定位頭文件、庫文件&#xff0c;并設置相關變量&#xff0c;以便后續編譯和鏈接。以下是詳細解析&#xff1a; 1. 基本語法 find_package(<PackageName&g…

Spring--BeanFactoryPostProcessor的用法

原文網址&#xff1a;Spring--BeanFactoryPostProcessor的用法_IT利刃出鞘的博客-CSDN博客 簡介 說明 本文介紹Spring的BeanFactoryPostProcessor的用法。 BeanPostProcessor和BeanFactoryPostProcessor的區別 項BeanPostProcessorBeanFactoryPostProcessor處理的對象處理…

了解類加載器嗎?類加載器的類型有哪些?

一、什么是類加載器&#xff08;ClassLoader&#xff09; 類加載器是 Java 虛擬機中的一部分&#xff0c;負責將 .class 文件加載到 JVM 內存中&#xff0c;生成對應的 Class 對象。 Java 程序中所有的類在使用前都必須通過類加載器加載進 JVM&#xff0c;才能被執行。二、類加…

PHP面向對象高級特性:魔術方法、對象迭代器與設計模式應用

引言 在前一篇文章中,我們探討了PHP的Traits、匿名類和對象比較機制。本文將深入PHP面向對象編程的更多高級特性,包括魔術方法、對象迭代器以及常用設計模式的實際應用,這些特性能夠幫助開發者構建更加靈活和強大的面向對象系統。 魔術方法深度解析 魔術方法是PHP中一組以…

【Java基礎】一個月教你輕松掌握Java——第三篇Git

一、Java概述&#xff08;之前的文章&#xff09;二、版本控制工具Git其實這個與Java基礎關系不大&#xff0c;但是這個工具還是很重要的&#xff0c;不管是團隊之間打比賽還是就業都應該學會它&#xff0c;秉持著學的早一些&#xff0c;用的時間長一點&#xff0c;會更熟練。&…

【C# in .NET】16. 探秘類成員-索引器:通過索引訪問對象

探秘類成員-索引器:通過索引訪問對象 在 C# 中,索引器(Indexer)是一種獨特的類成員,它允許類或結構的實例像數組一樣被索引訪問,為數據訪問提供了極大的靈活性。本文將從基礎概念出發,深入.NET 框架底層,剖析索引器的實現機制,并通過實戰案例展示其強大的應用價值。 …

idea出現:java: Target level ‘1.7‘ is incompatible with source level ‘1.8‘.解決辦法

在文件->設置->java編譯器&#xff0c;把這里版本對應上。這里用的是8版本

ssms(SQL 查詢編輯器) 添加快捷鍵 Ctrl+D(功能等于Ctrl+C + Ctrl+V),一步到位

1,打開ssms 工具&#xff0c;打開對應添加快捷鍵得地方2&#xff0c;分配 快捷鍵3&#xff0c;看效果

數學建模--層次分析法

層次分析法&#xff08;AHP&#xff09;筆記 一、核心概念 &#xff08;一&#xff09;問題本質 面對多方案、多準則決策&#xff0c;將復雜問題分層拆解&#xff0c;通過定性與定量結合&#xff0c;確定各因素權重&#xff0c;選出最優方案&#xff0c;比如選“微博之星”時綜…

人工智能教研室暑期培訓flask全棧開發培訓

人工智能教研室暑期培訓flask全棧開發培訓第一天&#xff1a;Flask 基礎入門與環境搭建實踐項目&#xff1a;搭建個人博客首頁&#xff0c;包含文章列表與詳情頁上午&#xff1a;環境搭建與 Flask 基礎1. 安裝 Python 與虛擬環境配置2. Flask 框架簡介與第一個 "Hello Wor…