国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

詳解一道高頻算法題:數組中的第 K 個最大元素

算法與數據結構 ? 來源:五分鐘學算法 ? 2020-06-03 17:37 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

今天分享的題目來源于 LeetCode 第 215 號問題,是面試中的高頻考題。

題目描述

在 未排序 的數組中找到第 k 個最大的元素。請注意,你需要找的是數組排序后的第 k 個最大的元素,而不是第 k 個不同的元素。

示例 1:

輸入:[3,2,1,5,6,4]和k=2 輸出:5

示例 2:

輸入:[3,2,3,1,2,4,5,5,6]和k=4 輸出:4

說明:

你可以假設 k 總是有效的,且 1 ≤ k ≤ 數組的長度。

題目解析

方法一:返回升序排序以后索引為 len - k 的元素

題目已經告訴你了:

你需要找的是數組排序后的第 k 個最大的元素,而不是第 k 個不同的元素。

因此,升序排序以后,返回索引為 len - k 這個元素即可。

這是最簡單的思路,如果只答這個方法,可能面試官并不會滿意,但是在我們平時的開發工作中,還是不能忽視這種思路簡單的方法,我認為理由如下:

1、最簡單同時也一定是最容易編碼的,編碼成功的幾率最高,可以用這個最簡單思路編碼的結果和其它思路編碼的結果進行比對,驗證高級算法的正確性;

2、在數據規模小、對時間復雜度、空間復雜度要求不高的時候,真沒必要上 “高大上” 的算法;

3、思路簡單的算法考慮清楚了,有些時候能為實現高級算法鋪路。這道題正是如此,“數組排序后的第 k 個最大的元素” ,語義是從右邊往左邊數第 k 個元素(從 1 開始),那么從左向右數是第幾個呢,我們列出幾個找找規律就好了。

一共 6 個元素,找第 2 大,索引是 4;
一共 6 個元素,找第 4 大,索引是 2。

因此,目標元素的索引是 len - k,即找最終排定以后位于 len - k 的那個元素;

4、低級算法往往容錯性最好,即在輸入不滿足題目條件的時候,往往還能得到正確的答案,而高級算法對輸入數據的要求就非常苛刻。

參考代碼

importjava.util.Arrays; publicclassSolution{ publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; Arrays.sort(nums); returnnums[len-k]; } }

復雜度分析

時間復雜度:O(NlogN)。這里 N 是數組的長度,算法的性能消耗主要在排序,JDK 默認使用快速排序,因此時間復雜度為O(NlogN)。

空間復雜度:O(1)。這里是原地排序,沒有借助額外的輔助空間。

到這里,我們已經分析出了:

1、我們應該返回最終排定以后位于 len - k 的那個元素;
2、性能消耗主要在排序,JDK 默認使用快速排序。

學習過 “快速排序” 的朋友,一定知道一個操作叫 partition,它是 “分而治之” 思想當中 “分” 的那一步。

經過 partition 操作以后,每一次都能排定一個元素,并且這個元素左邊的數都不大于它,這個元素右邊的數都不小于它,并且我們還能知道排定以后的元素的索引。

于是可以應用 “減而治之”(分治思想的特例)的思想,把問題規模轉化到一個更小的范圍里。

于是得到方法二。

方法二:借助 partition 操作定位

方法二則是借助 partition 操作定位到最終排定以后索引為 len - k 的那個元素。

以下的描述基于 “快速排序” 算法知識的學習,如果忘記的朋友們可以翻一翻自己的《數據結構與算法》教材,復習一下,partition 過程、分治思想和 “快速排序” 算法的優化。

【圖解數據結構】 一組動畫徹底理解快速排序

我們在學習 “快速排序” 的時候,接觸的第 1 個操作就是 partition(切分),簡單介紹如下:

partition(切分)操作,使得:

對于某個索引 j,nums[j] 已經排定,即 nums[j] 經過 partition(切分)操作以后會放置在它 “最終應該放置的地方”;

nums[left] 到 nums[j - 1] 中的所有元素都不大于 nums[j];

nums[j + 1] 到 nums[right] 中的所有元素都不小于 nums[j]。

partition(切分)操作總能排定一個元素,還能夠知道這個元素它最終所在的位置,這樣每經過一次 partition操作就能縮小搜索的范圍,這樣的額思想叫做 “減而治之”(是 “分而治之” 思想的特例)。

切分過程可以不借助額外的數組空間,僅通過交換數組元素實現。下面是參考代碼:

參考代碼

publicclassSolution{ publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; intleft=0; intright=len-1; //轉換一下,第k大元素的索引是len-k inttarget=len-k; while(true){ intindex=partition(nums,left,right); if(index==target){ returnnums[index]; }elseif(indextarget; right=index-1; } } } /** *在nums數組的[left,right]部分執行partition操作,返回nums[i]排序以后應該在的位置 *在遍歷過程中保持循環不變量的語義 *1、(left,k]=nums[left] * *@paramnums *@paramleft *@paramright *@return */ publicintpartition(int[]nums,intleft,intright){ intpivot=nums[left]; intj=left; for(inti=left+1;i<=?right;?i++)?{ ????????????if?(nums[i]?

復雜度分析

時間復雜度:O(N)。這里 N 是數組的長度。

空間復雜度:O(1)。這里是原地排序,沒有借助額外的輔助空間。

方法三:優先隊列

優先隊列的寫法就很多了,這里例舉一下我能想到的。

假設數組有 len 個元素。

思路 1 :把 len 個元素都放入一個最小堆中,然后再 pop() 出 len - k 個元素,此時最小堆只剩下 k 個元素,堆頂元素就是數組中的第 k 個最大元素。

思路 2 :把 len 個元素都放入一個最大堆中,然后再 pop() 出 k - 1 個元素,因為前 k - 1 大的元素都被彈出了,此時最大堆的堆頂元素就是數組中的第 k 個最大元素。

思路 3 :只用 k 個容量的優先隊列,而不用全部 len 個容量。

思路 4:用 k + 1 個容量的優先隊列,使得上面的過程更“連貫”一些,到了 k 個以后的元素,就進來一個,出去一個,讓優先隊列自己去維護大小關系。

思路 5:綜合考慮以上兩種情況,總之都是為了節約空間復雜度。即 k 較小的時候使用最小堆,k 較大的時候使用最大堆。

根據以上思路,分別寫出下面的代碼:

思路 1 參考代碼

//思路 1 :把`len`個元素都放入一個最小堆中,然后再 pop()出 len - k 個元素,此時最小堆只剩下`k`個元素,堆頂元素就是數組中的第`k`個最大元素。 importjava.util.PriorityQueue; publicclassSolution{ publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; //使用一個含有 len 個元素的最小堆,默認是最小堆,可以不寫 lambda 表達式:(a, b)-> a - b PriorityQueueminHeap=newPriorityQueue<>(len,(a,b)->a-b); for(inti=0;i

思路 2 參考代碼

//思路 2 :把`len`個元素都放入一個最大堆中,然后再 pop()出 k - 1 個元素,因為前 k - 1 大的元素都被彈出了,此時最大堆的堆頂元素就是數組中的第`k`個最大元素。 importjava.util.PriorityQueue; publicclassSolution{ publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; //使用一個含有 len 個元素的最大堆,lambda 表達式應寫成:(a, b)-> b - a PriorityQueuemaxHeap=newPriorityQueue<>(len,(a,b)->b-a); for(inti=0;i

思路 3 參考代碼

//思路 3 :只用`k`個容量的優先隊列,而不用全部`len`個容量。 importjava.util.PriorityQueue; publicclassSolution{ publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; //使用一個含有k個元素的最小堆 PriorityQueueminHeap=newPriorityQueue<>(k,(a,b)->a-b); for(inti=0;itopEle){ minHeap.poll(); minHeap.add(nums[i]); } } returnminHeap.peek(); } }

思路 4 參考代碼

//思路 4:用`k + 1`個容量的優先隊列,使得上面的過程更“連貫”一些,到了`k`個以后的元素,就進來一個,出去一個,讓優先隊列自己去維護大小關系。 importjava.util.PriorityQueue; publicclassSolution{ publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; //最小堆 PriorityQueuepriorityQueue=newPriorityQueue<>(k+1,(a,b)->(a-b)); for(inti=0;i

思路 5 參考代碼

//思路 5:綜合考慮以上兩種情況,總之都是為了節約空間復雜度。即`k`較小的時候使用最小堆,`k`較大的時候使用最大堆。 importjava.util.PriorityQueue; publicclassSolution{ //根據k的不同,選最大堆和最小堆,目的是讓堆中的元素更小 //思路 1:k 要是更靠近0的話,此時 k 是一個較大的數,用最大堆 //例如在一個有6個元素的數組里找第5大的元素 //思路 2:k 要是更靠近 len 的話,用最小堆 //所以分界點就是k=len-k publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; if(k<=?len?-?k)?{ ????????????//?System.out.println("使用最小堆"); ????????????//?特例:k = 1,用容量為 k 的最小堆 ????????????//?使用一個含有?k?個元素的最小堆 ????????????PriorityQueueminHeap=newPriorityQueue<>(k,(a,b)->a-b); for(inti=0;itopEle){ minHeap.poll(); minHeap.add(nums[i]); } } returnminHeap.peek(); }else{ //System.out.println("使用最大堆"); assertk>len-k; //特例:k = 100,用容量為 len - k + 1 的最大堆 intcapacity=len-k+1; PriorityQueuemaxHeap=newPriorityQueue<>(capacity,(a,b)->b-a); for(inti=0;i

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4784

    瀏覽量

    98060
  • 數組
    +關注

    關注

    1

    文章

    420

    瀏覽量

    27364

原文標題:超詳細!詳解一道高頻算法題:數組中的第 K 個最大元素

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    單片機常用的14C語言算法分享

    ) 基本思想:(將相鄰兩個數比較,小的調到前頭) 1)有n個數(存放在數組a(n)),第趟將每相鄰兩個數比較,小的調到前頭,經n-1次兩兩相鄰比較后,最大的數已“沉底”,放在最后
    發表于 01-29 06:59

    C語言插入排序算法和代碼

    和待插入的元素。第輪時,將第一個元素作為排序好的子數組,插入第二
    發表于 01-15 06:44

    3秒響應、實時告警!智能井蓋如何成為城市安全的“第一道防線”?

    IP68防護、-40℃~80℃寬溫運行及10年超長續航,支持自定義報警閾值與多級告警機制,大幅降低誤報率。作為城市物聯網感知層的關鍵節點,智能井蓋已融入智慧城管與應急管理體系,成為守護市民腳下安全的“第一道防線”。
    的頭像 發表于 12-09 11:57 ?362次閱讀
    3秒響應、實時告警!智能井蓋如何成為城市安全的“第<b class='flag-5'>一道</b>防線”?

    線性搜索與二分搜索介紹

    線性搜索(Linear Search):從數組的第一個元素開始,依次將當前元素與目標值進行比較,直到找到目標值或搜索完整個數組。 二分搜索(
    發表于 12-01 07:36

    數組的初體驗

    名稱[1] = 元素2; 數組名稱[n-1] = 元素n; 我們將數據放到數組之后又如何獲取數組
    發表于 11-25 08:06

    二維數組介紹

    定義是這樣的: int array[n][m] 訪問: array[a] 那么被訪問元素地址的計算方式就是: array + (m * a + b) 這個就是二維數組在內存的本質,其實和
    發表于 11-25 07:42

    不間斷電源(UPS):電力保障的“最后一道防線”

    (UninterruptiblePowerSupply,簡稱UPS)作為電力保障的“最后一道防線”,通過儲能裝置與智能轉換技術,在市電中斷時實現零切換時間供電,成為現代社會的“電力守護者”。、UP
    的頭像 發表于 10-29 09:02 ?1338次閱讀
    不間斷電源(UPS):電力保障的“最后<b class='flag-5'>一道</b>防線”

    RISCV-K指令集擴展分享

    的計算。 在Decode模塊中用于對K類型指令進行解碼的關鍵代碼: K擴展的針對的AES加密算法主要由以下四步驟組成:AddRoundKey:矩陣
    發表于 10-23 06:12

    電能質量在線監測裝置的高頻噪聲濾波功能有哪些參數可以配置?

    )動態調整,以實現 “精準濾除噪聲、完整保留有用信號” 的目標。以下是可配置的核心參數及其工程意義: 、硬件濾波參數(信號采集前端) 硬件濾波是高頻噪聲抑制的 “第一道防線”,其參數配置直接影響噪聲衰減能力與有用信號完整性。
    的頭像 發表于 10-15 16:43 ?551次閱讀

    頂堅國產防爆手持終端如何成為石化企業安全生產的第一道防線

    頂堅國產防爆手持終端之所以能成為石化企業安全生產的第一道防線,源于其通過防爆設計、功能集成、實時交互與系統協同,從物理安全、功能安全、管理安全、應急安全等維度,覆蓋了安全生產的全流程(預防、監測
    的頭像 發表于 08-26 10:31 ?842次閱讀
    頂堅國產防爆手持終端如何成為石化企業安全生產的第<b class='flag-5'>一道</b>防線

    【嘉楠堪智K230開發板試用體驗】高校競賽-2025電賽-E

    2025年全國大學生電子設計大賽本科組有三題目涉及視覺,K230的選用率也很高,所以我的視角簡單分析K230在本次電賽的優勢,以及01studio廠商
    發表于 08-21 15:32

    水文監測的雙軌纜小車和鉛魚纜小車

    一道堅實的科技防線,那么這兩設備有什么區別呢,原理又是怎么樣的呢?本文將探究竟。 ? ? ? ? 雙軌纜小車:通過兩根平行的軌道來引導小車的運行,利用電機或其他動力裝置驅動小車在
    的頭像 發表于 04-11 15:15 ?986次閱讀
    水文監測<b class='flag-5'>中</b>的雙軌纜<b class='flag-5'>道</b>小車和鉛魚纜<b class='flag-5'>道</b>小車

    成品電池綜合測試儀:電池品質的最后一道把關人

    綜合測試儀便成為了電池生產線上的“最后一道把關人”,為電池品質保駕護航。 成品電池綜合測試儀的重要性 成品電池綜合測試儀,是種集多種測試功能于體的專業設備,能夠對電池進行全面的性能測試和評估。從電池的容量、
    的頭像 發表于 03-18 14:30 ?725次閱讀

    SVPWM的原理及法則推導和控制算法詳解

    SVPWM 是近年發展的種比較新穎的控制方法,是由三相功率逆變器的六功率開關元件組成的特定開關模式產生的脈寬調制波,能夠使輸出電流波形盡 可能接近于理想的正弦波形。空間電壓矢量 PWM 與傳統
    發表于 03-14 14:51

    stm32 DMA串口接收到數組數組元素順序錯亂怎么解決?

    配置DMA循環模式,使用HAL_UART_Receive_DMA(&huart1,buffer,4)函數將串口數據循環發送到4元素的buffer數組內,上位機20ms發送
    發表于 03-12 08:02