【Python】優雅的快速選擇 - 快速排序 - 隨機快速排序

快速選擇(遞歸實現版)

這里給出以 “leetcode215. 數組中的第K個最大元素”為例的代碼。

class Solution:def findKthLargest(self, nums, k):self.nums = numsn = len(nums)return self.quickSelect(0,n-1,n-k)def quickSelect(self,l,r,k): # 手擼快速選擇if(l == r): return self.nums[k]mid_num = self.nums[l]i = l-1j = r+1while(i < j):i += 1while(self.nums[i] < mid_num): i += 1j -= 1while(self.nums[j] > mid_num): j -= 1if(i < j): self.nums[i],self.nums[j] = self.nums[j],self.nums[i]if(k <= j): return self.quickSelect(l,j,k)return self.quickSelect(j+1,r,k)

代碼的實現參照了官解,非常優雅。

代碼的關鍵是,"while(i < j):"這一步里面的循環。可以證明,經過這個循環,最后出來的j,其位置一定在區間[l,r-1]上,同時[l,j]元素的值均等小于等于[j+1,r]。因此,每次遞歸,都會導致輸入的數組長度減少,遞歸可以退出。由于尋找的是下標為k的排序的元素,因此每次分割,一定可以確定有一邊是不必再排序的,因此進入下一遞歸的區間,就選擇[l,j]或[j+1,r],直到某個遞歸中l=r,這時代表只有一個元素,沒必要排序,直接返回此時列表的下標k的元素即可得到。

注意代碼實現中的,選擇第一個元素作為基準值的設計很精妙,可以仔細品鑒。

快速選擇(迭代實現)

class Solution:def findKthLargest(self, nums, k):self.nums = numsn = len(nums)return self.quickSelectIter(0,n-1,n-k) def quickSelectIter(self,l,r,k): # 手擼快速選擇while(l != r):mid_num = self.nums[l]i = l-1j = r+1while(i < j):i += 1while(self.nums[i] < mid_num): i += 1j -= 1while(self.nums[j] > mid_num): j -= 1if(i < j): self.nums[i],self.nums[j] = self.nums[j],self.nums[i]if(k <= j):l,r = l,jelse:l,r = j+1,rreturn self.nums[k]

快速排序

上面的快速選擇,每次劃分成兩個區間,然后拋棄另一個區間,繼續劃分留下的區間。
對上面的代碼稍加改進,對每個劃分出的區間繼續劃分,即可得到完全排序的數組。

這里以"leetcode 912. 排序數組"給出代碼

class Solution:def sortArray(self, nums: List[int]) -> List[int]:self.nums = numsself.quickSort(0,len(nums)-1)return numsdef quickSort(self,l,r):if(l == r): returnmid_num = self.nums[l]i = l-1j = r+1while(i < j):i += 1while(self.nums[i] < mid_num): i += 1j -= 1while(self.nums[j] > mid_num): j -= 1if(i < j): self.nums[i],self.nums[j] = self.nums[j],self.nums[i]self.quickSort(l,j)self.quickSort(j+1,r)

隨機快速排序

上面的快速排序,取第一個元素為基準值,會導致在極端情況下,時間開銷大。比如數組已經是有序的情況。

這里做出改進,隨機選取數組中的一個元素作為基準值。但是,前面快速選擇的方法中實現的劃分是精心設計的,其要求基準值是第一個元素。
因此,在隨機選擇基準值并劃分的實現上,只需先隨機選取一個下標,并將下標值和第一個值互換,其它操作和之前一樣即可。

class Solution:def sortArray(self, nums: List[int]) -> List[int]:self.nums = numsself.quickSortRandom(0,len(nums)-1)return nums# 隨機快速排序def quickSortRandom(self,l,r):if(l == r): returnrandom_index = random.randint(l, r)self.nums[l],self.nums[random_index] = self.nums[random_index],self.nums[l]mid_num = self.nums[l]i = l-1j = r+1while(i < j):i += 1while(self.nums[i] < mid_num): i += 1j -= 1while(self.nums[j] > mid_num): j -= 1if(i < j): self.nums[i],self.nums[j] = self.nums[j],self.nums[i]self.quickSortRandom(l,j)self.quickSortRandom(j+1,r)

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

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

相關文章

Vue3實戰筆記(64)—Vue 3自定義指令的藝術:實戰中的最佳實踐

文章目錄 前言一、一些簡單的Vue3自定義指令超實用案例總結 前言 書接上文&#xff0c;在Vue3中&#xff0c;自定義指令是一種強大的工具&#xff0c;允許我們擴展HTML元素的功能。通過自定義指令&#xff0c;我們可以創建可重用的行為&#xff0c;并將它們綁定到任何元素上。…

訂單折扣金額分攤算法|代金券分攤|收銀系統|積分分攤|分攤|精度問題|按比例分配|錢分攤|錢分配

一個金額分攤的算法&#xff0c;將折扣分攤按比例&#xff08;細單實收在總體的占比&#xff09;到各個細單中。 此算法需要達到以下要求&#xff1a; 折扣金額接近細單總額&#xff0c;甚至折扣金額等于細單金額&#xff0c;某些時候甚至超過細單總額&#xff0c;要保證實收不…

游泳哪個牌子好?6大游泳耳機選購技巧總結分享

游泳耳機作為水上運動愛好者和游泳專業人士的必備裝備&#xff0c;不僅要能夠抵御水的侵入&#xff0c;還要提供清晰的音質和舒適的佩戴體驗。在市面上&#xff0c;不同品牌的游泳耳機琳瑯滿目&#xff0c;選擇起來可能會令人頭疼。本文旨在為您提供一份詳盡的游泳耳機選購指南…

每日一練 - Routing Policy節點邏輯

01 真題題目 一個 routing-policy 下可以有多個節點,不同節點號用 node 標識,每個節點下可以有多個if-match 和 apply 子句,下面哪些描述是錯誤的? A. 不同節點之間是“或"的關系 B. 當路由與該節點的任意一個 if-match 條件匹配失敗后&#xff0c;系統自動轉入下一節點…

Gemma輕量級開放模型在個人PC上釋放強大性能,讓每個桌面秒變AI工作站

Google DeepMind團隊最近推出了Gemma&#xff0c;這是一個基于其先前Gemini模型研究和技術的開放模型家族。這些模型專為語言理解、推理和安全性而設計&#xff0c;具有輕量級和高性能的特點。 Gemma 7B模型在不同能力領域的語言理解和生成性能&#xff0c;與同樣規模的開放模型…

名企專訪|對抗價格內卷,格行隨身WiFi如何持續三年爆火引領潮流

近期要是問網紅達人最喜歡帶貨的單品是什么&#xff1f;那一定有格行隨身WiFi的一席之地。能聚集了如此多的明星達人&#xff0c;僅僅是一句帶貨收益高顯然無法說服大家。顯然這里面還有著不為人知的秘密&#xff0c;先鋒財經特意專訪了格行隨身WiFi的創始人劉永先先生&#xf…

8.x86游戲實戰-OD詳解

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 本次游戲沒法給 內容參考于&#xff1a;微塵網絡安全 上一個內容&#xff1a;7.x86游戲實戰-C實現跨進程讀寫-跨進程寫內存 工具下載&#xff1a;下載 OllyI…

嵌入式Linux之Uboot簡介和移植

uboot簡介 uboot 的全稱是 Universal Boot Loader&#xff0c;uboot 是一個遵循 GPL 協議的開源軟件&#xff0c;uboot是一個裸機代碼&#xff0c;可以看作是一個裸機綜合例程。現在的 uboot 已經支持液晶屏、網絡、USB 等高級功能。 也就是說&#xff0c;可以在沒有系統的情況…

[我靠升級逆襲成為大師]韓漫日漫無刪減完整版,免費在線觀看漫畫

[我靠升級逆襲成為大師]韓漫日漫無刪減完整版&#xff0c;免費在線觀看漫畫 不能多說&#xff0c;怕審-核不過&#xff0c;自己看圖吧。 目前統計【統計日期&#xff1a;2024-07-03】&#xff1a; 完結的有&#xff1a;420部。 連載的有&#xff1a;308部&#xff0c;持續更…

生單鏈路流程復雜,涉及到上下游商品、庫存、營銷、風控、拆單、校驗、落庫等等十多個節點操作,需要保證數據的完整性和正確性

處理復雜的生單鏈路流程&#xff0c;確保數據的完整性和正確性&#xff0c;需要一個綜合的策略&#xff0c;包括但不限于以下幾個方面&#xff1a; 1. **流程設計**&#xff1a; - 明確每個節點的職責和輸入輸出&#xff0c;確保流程的邏輯清晰。 2. **數據校驗**&#xf…

python庫(1):Nuitka庫

1 Nuitka介紹 Nuitka是一個 Python 解釋器的替代品&#xff0c;支持CPython提供的代碼&#xff0c;可編譯 Python 代碼到 C 程序&#xff0c;并使用 libpython 來執行這些代碼&#xff0c;就像 CPython 一樣。 這讓你可以在沒有安裝 Python 的環境中運行 Python 程序&#xf…

AC7801時鐘配置流程

一 默認配置 在啟動文件中&#xff0c;已經對時鐘進行了初始化&#xff0c;默認按外部8M晶振&#xff0c;配置系統時鐘為48MHZ&#xff0c;APB為系統時鐘的2分頻&#xff0c;為24MHZ。在system_ac780x.c文件中&#xff0c;可以找到下面這個系統初始化函數&#xff0c;里面有Se…

前端修改audio背景色

1.查看瀏覽器設置Show user agent shadow DOM是否打開 2.打開可以查看audio Dom /** 去掉默認的背景顏色 */ audio::-webkit-media-controls-enclosure{background-color:unset; } 3.效果圖

Java官網網址及其重要資源

Java是一種廣泛應用于開發各種應用程序的編程語言&#xff0c;它具有跨平臺、面向對象和高性能等優勢。若你想學習Java或深入了解它的最新動態&#xff0c;Java官網是你的首要目的地。在本文中&#xff0c;我們將向你介紹Java官網的網址以及一些重要資源。 Java官網網址&#x…

TCP/IP 網絡協議族分層

TCP/IP協議族 TCP/IP不單是TCP和IP兩個協議&#xff0c;TCP/IP實際上是一組協議&#xff0c;它包括上百個各種功能的協議&#xff0c;如&#xff1a;遠程登錄、文件傳輸和電子郵件等&#xff0c;當然&#xff0c;也包括TCP、IP協議 它將軟件通信過程抽象化為四個抽象層&#…

基于SpringBoot校園外賣配送系統設計和實現(源碼+LW+調試文檔+講解等)

&#x1f497;博主介紹&#xff1a;?全網粉絲10W,CSDN作者、博客專家、全棧領域優質創作者&#xff0c;博客之星、平臺優質作者、專注于Java、小程序技術領域和畢業項目實戰?&#x1f497; &#x1f31f;文末獲取源碼數據庫&#x1f31f; 感興趣的可以先收藏起來&#xff0c;…

c++:關鍵字異常處理機制

模板編程的幾個關鍵字 模(mu)板編程初體驗 (1)template和typename (2)模板實際上是一種抽象&#xff0c;C的高級編程特性就是不斷向抽象化發展 export (1)用來在cpp文件中定義一個模板類或模板函數&#xff0c;而它的聲明在對應的h文件中 (2)export專用于模板&#xff0c;類似…

揭秘電子世界的雙雄:模擬電路與數字電路的精彩對決!

數字電路與模擬電路&#xff0c;這兩者在電子工程領域可謂是兩大基石&#xff0c;各有千秋&#xff0c;各自發揮著不可或缺的作用。下面&#xff0c;我們就來詳細探討一下它們之間的主要區別。 1. 信號類型與處理 模擬電路&#xff1a;處理的是連續變化的信號&#xff0c;就像…

使用阿里云語音服務實現設備異常實時通知

隨著物聯網的普及,設備異常通知方式也變得多種多樣。從傳統的后臺異常列表,到短信通知,再到微信消息通知等。然而,當設備探測到火警等緊急異常時,需要實時通知到相關人員。本文將介紹如何借助阿里云的語音服務來實現這一功能。 1. 準備工作 1.1 資質申請 首先,登錄阿里…

Git中fetch與pull 的區別

一、fetch與pull的基本概念 在Git中&#xff0c;fetch和pull都是用于從遠程倉庫獲取數據的命令。但是&#xff0c;它們在處理方式和結果上有所不同。 1、fetch fetch命令用于從遠程倉庫下載最新的數據到本地倉庫&#xff0c;但它不會自動合并或修改當前的工作。fetch會將遠程…