C++ 快速排序快速選擇

目錄

1、75. 顏色分類

2、912. 排序數組

3、?215. 數組中的第K個最大元素

4、LCR 159. 庫存管理 III


1、75. 顏色分類

?思路:利用快速排序思路,使用三指針分塊進行優化。

  • [0,left]——小于key
  • [left+1,right-1]——等于key
  • [right,nums.size()]——大于key
class Solution {
public:void sortColors(vector<int>& nums) {int n = nums.size();int left = -1, right = n, cur = 0;while (cur < right) {if (nums[cur] == 0)swap(nums[++left], nums[cur++]);else if (nums[cur] == 2)swap(nums[--right], nums[cur]);elsecur++;}}
};

2、912. 排序數組

?

思路:快排+三指針優化+隨機選擇基準元素

class Solution {
public:vector<int> sortArray(vector<int>& nums) {srand(time(NULL));qsort(nums,0,nums.size()-1);return nums;}int getRandom(vector<int>& nums,int left,int right){int i=rand();return nums[i%(right-left+1)+left];}void qsort(vector<int>& nums,int begin,int end){if(begin >= end)return;int i=begin,left=begin-1,right=end+1;int key=getRandom(nums,begin,end);while(i<right){if(nums[i]<key)swap(nums[++left],nums[i++]);else if(nums[i]>key)swap(nums[--right],nums[i]);elsei++;}qsort(nums,begin,left);qsort(nums,right,end);}
};

3、?215. 數組中的第K個最大元素

思路:快速選擇(快排+三指針分塊+隨機選擇基準元素+遞歸排序時進入對應區間)

  • 第k個最大元素也就是排序(升序)后的倒數第k個

? ? ?<key? ? ? ? ? ? ? ?=key? ? ? ? ? ? ? ? >key
|————|————————|—————|

l? ? ? ? ? left left+1? ? ? ? right-1 right? ? ? ? ? ? ?r

? ? ? ? a? ? ? ? ? ? ? ? ? ? b? ? ? ? ? ? ? ? ? ? ? ? c(區間元素個數)

c表示在當前key(基準值)右側的元素數量(即比key大的元素數量),b表示等于key的元素數量。由于我們是尋找第k個最大的元素,數組的右側代表了較大的元素。

  • if (c >= k):如果key右側的元素數量c大于或等于k,這意味著第k個最大的元素位于key的右側或者是key本身。因此,我們遞歸地在key右側的數組部分繼續進行快速選擇,尋找第k個最大的元素。

  • else if (b + c >= k):如果key右側的元素數量c加上等于key的元素數量b大于或等于k,這意味著第k個最大的元素要么是key本身,要么在等于key的這些元素中。由于這些元素都是相等的,我們可以直接返回key作為第k個最大的元素。

  • else:如果上述兩個條件都不滿足,這意味著第k個最大的元素位于key的左側。因此,我們遞歸地在pivot左側的數組部分繼續進行快速選擇。此時,我們需要調整k的值,因為我們已經排除了b + c個比key大或等于key的元素,所以新的k應該減去這部分已經排除的元素數量。

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {srand(time(NULL));return qsort(nums, 0, nums.size() - 1, k);}int qsort(vector<int>& nums, int l, int r, int k) {if (l == r)return nums[l];int key = getRandom(nums, l, r);int left = l - 1, right = r + 1, i = l;while (i < right) {if (nums[i] < key)swap(nums[++left], nums[i++]);else if (nums[i] > key)swap(nums[--right], nums[i]);elsei++;}int c = r - right + 1, b = right - left - 1;if (c >= k)return qsort(nums, right, r, k);else if (b + c >= k)return key;elsereturn qsort(nums, l, left, k - b - c);}int getRandom(vector<int>& nums, int left, int right) {return nums[rand() % (right - left + 1) + left];}
};

?為了找到數組中第k個最大的元素,并且要求時間復雜度為O(n),我們可以比較這些方法:

  1. 快速選擇算法(第一種方法):

    • 優點: 平均時間復雜度為O(n),符合題目要求。它通過隨機選擇一個樞軸來分割數組,然后只在包含第k個最大元素的那部分數組上遞歸,從而減少了不必要的計算。
    • 缺點: 最壞情況下的時間復雜度為O(n^2),但這種情況很少發生。算法的性能依賴于隨機數的選擇。
  2. 最小堆(第二種方法):

    • 優點: 對于找到第k個最大元素,這種方法維護了一個大小為k的最小堆,時間復雜度為O(n log k),適合k遠小于n的情況。
    • 缺點: 當k接近n時,性能不如快速選擇算法。
      class Solution {
      public:int findKthLargest(vector<int>& nums, int k) {priority_queue<int,vector<int>,greater<int>> pq(nums.begin(),nums.begin()+k);for(size_t i=k;i<nums.size();i++){if(nums[i]>pq.top()){pq.pop();pq.push(nums[i]);}}return pq.top();}
      };

  3. 排序(第三種方法):

    • 優點: 實現簡單,直觀易懂。
    • 缺點: 時間復雜度為O(n log n),不滿足題目對O(n)時間復雜度的要求。
      class Solution {
      public:int findKthLargest(vector<int>& nums, int k) {sort(nums.begin(),nums.end());return nums[nums.size()-k];}
      };
  4. 最大堆(第四種方法):

    • 優點: 通過構建一個最大堆,然后彈出k-1次,可以直接得到第k個最大元素。這種方法簡單且對于理解堆結構很有幫助。
    • 缺點: 時間復雜度為O(n + k log n),當k較小相對高效,但當k接近n時,性能下降。
      class Solution {
      public:int findKthLargest(vector<int>& nums, int k) {priority_queue<int> pq(nums.begin(),nums.end());while(--k){pq.pop();}return pq.top();}
      };

結論:

  • 如果你追求平均情況下的最優時間復雜度,并且可以接受在極少數情況下性能的不確定性,快速選擇算法是最佳選擇。
  • 如果k值較小,最小堆方法也是一個不錯的選擇,因為它可以較快地找到第k個最大的元素。
  • 排序方法雖然簡單,但不滿足題目對時間復雜度的要求。
  • 最大堆方法適用于k值較小的情況,但當k值較大時,性能不是最優的。

綜上所述,考慮到時間復雜度的要求和算法的效率,快速選擇算法是最符合題目要求的解決方案

4、LCR 159. 庫存管理 III

思路:快速選擇(快排+三指針分塊+隨機選擇基準元素+進入對應區間尋找)
? ? ?<key? ? ? ? ? ? ? ?=key? ? ? ? ? ? ? ? >key
|————|————————|—————|

l? ? ? ? ? left left+1? ? ? ? right-1 right? ? ? ? ? ? ?r

? ? ? ? a? ? ? ? ? ? ? ? ? ? b? ? ? ? ? ? ? ? ? ? ? ? c(區間元素個數)

a表示在當前的key(基準值)左邊的元素數量,b表示等于key的元素數量。cnt是我們需要找到的庫存余量最少的商品數量。

  • if (a > cnt):如果key左邊的元素數量a大于cnt,這意味著我們需要的cnt個最小元素全部位于key的左邊。因此,我們遞歸地在key左邊的數組部分繼續進行快速選擇,尋找這cnt個最小元素。

  • else if (a + b >= cnt):如果key左邊的元素數量a加上等于key的元素數量b大于或等于cnt,這意味著我們需要的cnt個最小元素已經包含在左邊的元素和等于key的元素中。由于題目說明返回順序不限,我們不需要進一步排序或選擇,可以直接返回結果。

  • else:如果上述兩個條件都不滿足,這意味著我們需要的cnt個最小元素部分位于key的右邊。因此,我們遞歸地在key右邊的數組部分繼續進行快速選擇。此時,我們需要調整cnt的值,因為我們已經找到了一部分所需的最小元素(即a + b個),所以新的cnt應該減去這部分已經找到的元素數量。

class Solution {
public:vector<int> inventoryManagement(vector<int>& stock, int cnt) {srand(time(NULL));qsort(stock, 0, stock.size() - 1, cnt);return {stock.begin(), stock.begin() + cnt};}int qsort(vector<int>& stock, int l, int r, int cnt) {if (l == r)return stock[l];int key = getRandom(stock, l, r);int left = l - 1, right = r + 1, i = l;while (i < right) {if (stock[i] < key)swap(stock[++left], stock[i++]);else if (stock[i] > key)swap(stock[--right], stock[i]);elsei++;}int a = left - l + 1, b = right - left - 1;if (a > cnt)return qsort(stock, l, left, cnt);else if (a + b >= cnt)return 0;elsereturn qsort(stock, right, r, cnt - b - a);}int getRandom(vector<int>& stock, int left, int right) {return stock[rand() % (right - left + 1) + left];}
};

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

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

相關文章

博途PLC 面向對象系列之“輸送帶控制功能塊“(SCL代碼)

這篇是面向對象系列之"輸送帶功能塊"的封裝,面向對象是系列文章,相關鏈接如下: 1、面向對象系列之找"對象" https://rxxw-control.blog.csdn.net/article/details/136150027https://rxxw-control.blog.csdn.net/article/details/1361500272、面向對象…

LeetCode 刷題 [C++] 第215題.數組中的第K個最大元素

題目描述 給定整數數組 nums 和整數 k&#xff0c;請返回數組中第 k 個最大的元素。 請注意&#xff0c;你需要找的是數組排序后的第 k 個最大的元素&#xff0c;而不是第 k 個不同的元素。 你必須設計并實現時間復雜度為 O(n) 的算法解決此問題。 題目分析 根據題意分析&…

MYSQL 刪除命令 delete、truncate 、drop

目錄 一、delete 二、truncate 三、drop 四、delete&#xff0c;drop&#xff0c;truncate的區別 一、delete 作用&#xff1a;僅僅刪除表數據&#xff0c;表結構保留&#xff0c;數據能回滾 命令格式 #刪除全部數據 delete from 表名;#刪除表中id為1的數據&#xff0c;…

CleanMyMac X2024一款專為Mac用戶設計的優化工具

親愛的用戶們&#xff0c;我們都知道電腦在長時間使用后會變得越來越慢&#xff0c;垃圾文件和無用的應用程序會占用我們的硬盤空間&#xff0c;讓我們的電腦變得像蝸牛一樣慢。但是&#xff0c;現在有一個解決方案可以讓你的電腦重獲新生&#xff0c;那就是CleanMyMac X&#…

oracle鎖表

select alter system kill session ||sess.sid||,||sess.serial#||; bb,sess.sid,sess.serial#, lo.oracle_username,--登錄賬號lo.os_user_name,--登錄電腦ao.object_name,--被鎖表名lo.locked_mode --鎖住級別from v$locked_object lo,dba_objects ao,v$session sess where a…

第七十一天 漏洞發現-Web框架中間件聯動GobyAfrogXrayAwvsVulmap

第71天 漏洞發現-Web框架中間件&聯動&Goby&Afrog&Xray&Awvs&Vulmap 知識點&#xff1a; 1、Bup簡單介紹&使用說明 2、Xray簡單介紹&使用說明 3、AWWS簡單介紹&使用說明 4、Goby簡單介紹&使用說明 5、Afrog簡單介紹&使用說明 6、…

泰迪智能科技企業數據挖掘平臺使用場景

企業數據挖掘平臺助力企業數據挖掘&#xff0c;數據挖掘平臺也在多個領域發揮著重要的作用。 企業數據挖掘平臺具有數據抓取、數據清洗、數據分析、機器學習等多項功能&#xff0c;廣泛應用于企業的各個領域&#xff0c;包括&#xff1a;金融行業、醫療行業、交通領域、教育、制…

學習linux從0到工程師(命令)-4

基本命令 uname -m 顯示機器的處理器架構 uname -r 顯示正在使用的內核版本 dmidecode -q 顯示硬件系統部件 (SMBIOS / DMI) hdparm -i /dev/hda 羅列一個磁盤的架構特性 hdparm -tT /dev/sda 在磁盤上執行測試性讀取操作系統信息 arch 顯示機器的處理器架構 uname -m 顯示機器…

在OceanBase使用中,如何優化因Join估算不準導致執行計劃選錯的問題

作者&#xff1a;胡呈清&#xff0c;愛可生公司旗下的DBA團隊成員&#xff0c;擅長故障分析和性能優化。愛可生開源社區出品&#xff0c;原創內容未經授權不得隨意使用&#xff0c;轉載請聯系小編并注明來源。本文約 1600 字&#xff0c;預計閱讀需要 15 分鐘。 數據庫版本&…

RunnerGo UI自動化測試腳本如何配置

RunnerGo提供從API管理到API性能再到可視化的API自動化、UI自動化測試功能模塊&#xff0c;覆蓋了整個產品測試周期。 RunnerGo UI自動化基于Selenium瀏覽器自動化方案構建&#xff0c;內嵌高度可復用的測試腳本&#xff0c;測試團隊無需復雜的代碼編寫即可開展低代碼的自動化…

OpenXR 超詳細的spec

3.API 初始化 3.2 Function Pointers XrResult xrGetInstanceProcAddr(XrInstance instance,const char* name,PFN_xrVoidFunction* function); instance: XrInstance類型&#…

【LeetCode】121. 買賣股票的最佳時機(簡單)——代碼隨想錄算法訓練營Day48

題目鏈接&#xff1a;121. 買賣股票的最佳時機 題目描述 給定一個數組 prices &#xff0c;它的第 i 個元素 prices[i] 表示一支給定股票第 i 天的價格。 你只能選擇 某一天 買入這只股票&#xff0c;并選擇在 未來的某一個不同的日子 賣出該股票。設計一個算法來計算你所能…

BetterDisplay Pro for Mac v2.0.11激活版:屏幕顯示優化專家

BetterDisplay Pro是一款由waydabber開發的Mac平臺上的顯示器校準軟件&#xff0c;可以幫助用戶調整顯示器的顏色和亮度&#xff0c;以獲得更加真實、清晰和舒適的視覺體驗。 軟件下載&#xff1a;BetterDisplay Pro for Mac v2.0.11激活版下載 &#x1f50d; 精準校準&#xf…

Unity的相機跟隨和第三人稱視角

Unity相機跟隨和第三人稱視角 介紹鏡頭視角跟隨人物方向進行旋轉的鏡頭視角固定球和人的鏡頭視角 思路跟隨人物方向進行旋轉的鏡頭視角固定球和人的鏡頭視角 鏡頭旋轉代碼人物移動的參考代碼注意 介紹 最近足球項目的鏡頭在做改動&#xff0c;觀察了一下實況足球的視角&#x…

npm digital envelope routines::unsupported

問題描述&#xff1a;npm運行命令報錯&#xff1a;digital envelope routines::unsupported 原因&#xff1a;node版本過高 解決方案&#xff1a;在運行命令之前加上 SET NODE_OPTIONS--openssl-legacy-provider && SET NODE_OPTIONS--openssl-legacy-provider &&a…

阿里云服務器免費6個月,居然又出了企業版

我之前收到了阿里云的免費6個月服務器&#xff0c;現在上面掛著一些網頁。 由于帶寬只有1M&#xff0c;所以用得不多。 今晚本來打算買臺新服務器&#xff0c;發現阿里云6個月免費促銷居然出了企業版。 之前只有一個版本。 我手頭正好有資源&#xff0c;于是又免費來了一臺服…

Eslint在Vscode中使用技巧的相關技巧

ps :該文章會詳細記錄構建一個腳手架遇到的問題&#xff0c;會持續更新&#xff0c;請定時查看 Eslint相關? 在vscode中使用eslint插件 在vscode中用戶配置沒有開啟eslint.enable 在vscode中工作區配置開啟eslint.enable settings.json中沒有做eslint相關配置 在編寫的vue…

敏捷方法簡介

敏捷方法簡介 特點 適應性&#xff0c;應對變化以人為本&#xff0c;發揮人的特性迭代增量式開發&#xff0c;逐版本更新 實踐 極限編程 特點 加強交流從簡單做起尋求反饋實事求是 水晶系列方法 特點 以人為中心&#xff0c;機動性一組經過證明、對不同類型項目非常有效…

【QT】Qt Charts概述

目錄 1 QtCharts模塊 2 圖表的主要組成部分 2.1 QChartView的功能 2.2 序列 2.3 坐標軸 2.4 圖例 3 一個簡單的QChart繪圖程序 QtCharts是Qt提供的圖表模塊&#xff0c;在Qt5.7以前只有商業版才有Qt Charts&#xff0c;但是從Qt5.7開始&#xff0c;社區版本也包含了Qt C…

藍橋杯倒計時41天!DFS進階1——回溯

DFS進階1——回溯 先說一下回溯的板子 dfs(){ for(......){標記信息dfs()撤銷標記 } }回溯模板——遞歸實現排列型枚舉 題目分析 其實就是對1~n的數字全排列&#xff0c;這里就可以用dfs去做&#xff0c;1~n全排列我其實是確定每一個位置我應該放哪一個數字&#xff0c;那么…