91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳解一道高頻算法題:數(shù)組中的第 K 個(gè)最大元素

算法與數(shù)據(jù)結(jié)構(gòu) ? 來(lái)源:五分鐘學(xué)算法 ? 2020-06-03 17:37 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

今天分享的題目來(lái)源于 LeetCode 第 215 號(hào)問(wèn)題,是面試中的高頻考題。

題目描述

在 未排序 的數(shù)組中找到第 k 個(gè)最大的元素。請(qǐng)注意,你需要找的是數(shù)組排序后的第 k 個(gè)最大的元素,而不是第 k 個(gè)不同的元素。

示例 1:

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

示例 2:

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

說(shuō)明:

你可以假設(shè) k 總是有效的,且 1 ≤ k ≤ 數(shù)組的長(zhǎng)度。

題目解析

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

題目已經(jīng)告訴你了:

你需要找的是數(shù)組排序后的第 k 個(gè)最大的元素,而不是第 k 個(gè)不同的元素。

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

這是最簡(jiǎn)單的思路,如果只答這個(gè)方法,可能面試官并不會(huì)滿意,但是在我們平時(shí)的開(kāi)發(fā)工作中,還是不能忽視這種思路簡(jiǎn)單的方法,我認(rèn)為理由如下:

1、最簡(jiǎn)單同時(shí)也一定是最容易編碼的,編碼成功的幾率最高,可以用這個(gè)最簡(jiǎn)單思路編碼的結(jié)果和其它思路編碼的結(jié)果進(jìn)行比對(duì),驗(yàn)證高級(jí)算法的正確性;

2、在數(shù)據(jù)規(guī)模小、對(duì)時(shí)間復(fù)雜度、空間復(fù)雜度要求不高的時(shí)候,真沒(méi)必要上 “高大上” 的算法;

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

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

因此,目標(biāo)元素的索引是 len - k,即找最終排定以后位于 len - k 的那個(gè)元素;

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

參考代碼

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

復(fù)雜度分析

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

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

到這里,我們已經(jīng)分析出了:

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

學(xué)習(xí)過(guò) “快速排序” 的朋友,一定知道一個(gè)操作叫 partition,它是 “分而治之” 思想當(dāng)中 “分” 的那一步。

經(jīng)過(guò) partition 操作以后,每一次都能排定一個(gè)元素,并且這個(gè)元素左邊的數(shù)都不大于它,這個(gè)元素右邊的數(shù)都不小于它,并且我們還能知道排定以后的元素的索引。

于是可以應(yīng)用 “減而治之”(分治思想的特例)的思想,把問(wèn)題規(guī)模轉(zhuǎn)化到一個(gè)更小的范圍里。

于是得到方法二。

方法二:借助 partition 操作定位

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

以下的描述基于 “快速排序” 算法知識(shí)的學(xué)習(xí),如果忘記的朋友們可以翻一翻自己的《數(shù)據(jù)結(jié)構(gòu)與算法》教材,復(fù)習(xí)一下,partition 過(guò)程、分治思想和 “快速排序” 算法的優(yōu)化。

【圖解數(shù)據(jù)結(jié)構(gòu)】 一組動(dòng)畫(huà)徹底理解快速排序

我們?cè)趯W(xué)習(xí) “快速排序” 的時(shí)候,接觸的第 1 個(gè)操作就是 partition(切分),簡(jiǎn)單介紹如下:

partition(切分)操作,使得:

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

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

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

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

切分過(guò)程可以不借助額外的數(shù)組空間,僅通過(guò)交換數(shù)組元素實(shí)現(xiàn)。下面是參考代碼:

參考代碼

publicclassSolution{ publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; intleft=0; intright=len-1; //轉(zhuǎn)換一下,第k大元素的索引是len-k inttarget=len-k; while(true){ intindex=partition(nums,left,right); if(index==target){ returnnums[index]; }elseif(indextarget; right=index-1; } } } /** *在nums數(shù)組的[left,right]部分執(zhí)行partition操作,返回nums[i]排序以后應(yīng)該在的位置 *在遍歷過(guò)程中保持循環(huán)不變量的語(yǔ)義 *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]?

復(fù)雜度分析

時(shí)間復(fù)雜度:O(N)。這里 N 是數(shù)組的長(zhǎng)度。

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

方法三:優(yōu)先隊(duì)列

優(yōu)先隊(duì)列的寫(xiě)法就很多了,這里例舉一下我能想到的。

假設(shè)數(shù)組有 len 個(gè)元素。

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

思路 2 :把 len 個(gè)元素都放入一個(gè)最大堆中,然后再 pop() 出 k - 1 個(gè)元素,因?yàn)榍?k - 1 大的元素都被彈出了,此時(shí)最大堆的堆頂元素就是數(shù)組中的第 k 個(gè)最大元素。

思路 3 :只用 k 個(gè)容量的優(yōu)先隊(duì)列,而不用全部 len 個(gè)容量。

思路 4:用 k + 1 個(gè)容量的優(yōu)先隊(duì)列,使得上面的過(guò)程更“連貫”一些,到了 k 個(gè)以后的元素,就進(jìn)來(lái)一個(gè),出去一個(gè),讓優(yōu)先隊(duì)列自己去維護(hù)大小關(guān)系。

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

根據(jù)以上思路,分別寫(xiě)出下面的代碼:

思路 1 參考代碼

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

思路 2 參考代碼

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

思路 3 參考代碼

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

思路 4 參考代碼

//思路 4:用`k + 1`個(gè)容量的優(yōu)先隊(duì)列,使得上面的過(guò)程更“連貫”一些,到了`k`個(gè)以后的元素,就進(jìn)來(lái)一個(gè),出去一個(gè),讓優(yōu)先隊(duì)列自己去維護(hù)大小關(guān)系。 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:綜合考慮以上兩種情況,總之都是為了節(jié)約空間復(fù)雜度。即`k`較小的時(shí)候使用最小堆,`k`較大的時(shí)候使用最大堆。 importjava.util.PriorityQueue; publicclassSolution{ //根據(jù)k的不同,選最大堆和最小堆,目的是讓堆中的元素更小 //思路 1:k 要是更靠近0的話,此時(shí) k 是一個(gè)較大的數(shù),用最大堆 //例如在一個(gè)有6個(gè)元素的數(shù)組里找第5大的元素 //思路 2:k 要是更靠近 len 的話,用最小堆 //所以分界點(diǎn)就是k=len-k publicintfindKthLargest(int[]nums,intk){ intlen=nums.length; if(k<=?len?-?k)?{ ????????????//?System.out.println("使用最小堆"); ????????????//?特例:k = 1,用容量為 k 的最小堆 ????????????//?使用一個(gè)含有?k?個(gè)元素的最小堆 ????????????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

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4786

    瀏覽量

    98256
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    420

    瀏覽量

    27404

原文標(biāo)題:超詳細(xì)!詳解一道高頻算法題:數(shù)組中的第 K 個(gè)最大元素

文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    EOL測(cè)試系統(tǒng)——電池包下線前的最后一道品質(zhì)防線

    在儲(chǔ)能電池包的生產(chǎn)線上,EOL測(cè)試系統(tǒng) 是產(chǎn)品交付前的最后一道關(guān)口,也是最重要的品質(zhì)防線。EOL測(cè)試的全面性與可靠性,直接決定了流入市場(chǎng)的儲(chǔ)能產(chǎn)品是否存在早期失效風(fēng)險(xiǎn)。 個(gè)完整的電池包EOL測(cè)試
    的頭像 發(fā)表于 03-23 16:40 ?181次閱讀
    EOL測(cè)試系統(tǒng)——電池包下線前的最后<b class='flag-5'>一道</b>品質(zhì)防線

    嵌入式春招筆試高頻算法(附解題思路)

    實(shí)現(xiàn)”的邏輯,幫你吃透解題技巧,舉反三。 、高頻算法1:數(shù)組排序(冒泡排序,必考) 嵌入式
    發(fā)表于 03-18 10:08

    單片機(jī)常用的14個(gè)C語(yǔ)言算法分享

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

    FFT算法原理詳解

    ]={1,1,1,1,1,1,1,1}; struct complex1{ //定義個(gè)復(fù)數(shù)結(jié)構(gòu)體 double real; //實(shí)部 double image; //虛部 }; //將input的實(shí)數(shù)結(jié)果
    發(fā)表于 01-22 06:36

    C語(yǔ)言插入排序算法和代碼

    和待插入的元素。第輪時(shí),將第一個(gè)元素作為排序好的子數(shù)組,插入第二個(gè)
    發(fā)表于 01-15 06:44

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

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

    線性搜索與二分搜索介紹

    線性搜索(Linear Search):從數(shù)組的第一個(gè)元素開(kāi)始,依次將當(dāng)前元素與目標(biāo)值進(jìn)行比較,直到找到目標(biāo)值或搜索完整個(gè)數(shù)組。 二分搜索(
    發(fā)表于 12-01 07:36

    數(shù)組的初體驗(yàn)

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

    二維數(shù)組介紹

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

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

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

    RISCV-K指令集擴(kuò)展分享

    的計(jì)算。 在Decode模塊中用于對(duì)K類(lèi)型指令進(jìn)行解碼的關(guān)鍵代碼: K擴(kuò)展的針對(duì)的AES加密算法主要由以下四個(gè)步驟組成:AddRoundKey:矩陣
    發(fā)表于 10-23 06:12

    電能質(zhì)量在線監(jiān)測(cè)裝置的高頻噪聲濾波功能有哪些參數(shù)可以配置?

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

    頂堅(jiān)國(guó)產(chǎn)防爆手持終端如何成為石化企業(yè)安全生產(chǎn)的第一道防線

    頂堅(jiān)國(guó)產(chǎn)防爆手持終端之所以能成為石化企業(yè)安全生產(chǎn)的第一道防線,源于其通過(guò)防爆設(shè)計(jì)、功能集成、實(shí)時(shí)交互與系統(tǒng)協(xié)同,從物理安全、功能安全、管理安全、應(yīng)急安全等維度,覆蓋了安全生產(chǎn)的全流程(預(yù)防、監(jiān)測(cè)
    的頭像 發(fā)表于 08-26 10:31 ?885次閱讀
    頂堅(jiān)國(guó)產(chǎn)防爆手持終端如何成為石化企業(yè)安全生產(chǎn)的第<b class='flag-5'>一道</b>防線

    【嘉楠堪智K230開(kāi)發(fā)板試用體驗(yàn)】高校競(jìng)賽-2025電賽-E

    2025年全國(guó)大學(xué)生電子設(shè)計(jì)大賽本科組有三題目涉及視覺(jué),K230的選用率也很高,所以我的視角簡(jiǎn)單分析K230在本次電賽的優(yōu)勢(shì),以及01studio廠商
    發(fā)表于 08-21 15:32

    水文監(jiān)測(cè)的雙軌纜小車(chē)和鉛魚(yú)纜小車(chē)

    一道堅(jiān)實(shí)的科技防線,那么這兩個(gè)設(shè)備有什么區(qū)別呢,原理又是怎么樣的呢?本文將探究竟。 ? ? ? ? 雙軌纜小車(chē):通過(guò)兩根平行的軌道來(lái)引導(dǎo)小車(chē)的運(yùn)行,利用電機(jī)或其他動(dòng)力裝置驅(qū)動(dòng)小車(chē)在
    的頭像 發(fā)表于 04-11 15:15 ?1051次閱讀
    水文監(jiān)測(cè)<b class='flag-5'>中</b>的雙軌纜<b class='flag-5'>道</b>小車(chē)和鉛魚(yú)纜<b class='flag-5'>道</b>小車(chē)