自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

拜托,別再問我貪心算法了!

開發(fā) 前端 算法
在求三角形最短路徑和時(shí),能否用貪心算法求解。所以本文打算對(duì)貪心算法進(jìn)行簡單地介紹,介紹完之后我們?cè)賮砜纯词欠襁@道三角形最短路徑問題能用貪心算法來求解。

[[323204]]

前言

在求三角形最短路徑和時(shí),能否用貪心算法求解。所以本文打算對(duì)貪心算法進(jìn)行簡單地介紹,介紹完之后我們?cè)賮砜纯词欠襁@道三角形最短路徑問題能用貪心算法來求解。

本文將會(huì)從以下幾個(gè)方面來介紹貪心算法

  • 什么是貪心算法
  • 貪心算法例題詳題
  • 貪心算法適用場景
  • 再看三角形最短路徑和是否能用貪心算法求解

什么是貪心算法

貪心算法是指在每個(gè)階段做選擇的時(shí)候都做出當(dāng)前階段(或狀態(tài))最好的選擇,并且期望這樣做到的結(jié)果是全局最優(yōu)解(但未必是全局最優(yōu)解)

貪心算法其實(shí)是動(dòng)態(tài)規(guī)劃的一種,由于它的「貪心」,只著眼于當(dāng)前階段的最優(yōu)解,所以每個(gè)子問題只會(huì)被計(jì)算一次,如果由此能得出全局最優(yōu)解,相對(duì)于動(dòng)態(tài)規(guī)劃要對(duì)每個(gè)子問題求全局最優(yōu)解,它的時(shí)間復(fù)雜度無疑是會(huì)下降一個(gè)量級(jí)的。

舉個(gè)簡單的例子,比如給定某個(gè)數(shù)字的金額(如 250)與 100, 50, 10, 5, 1 這些紙幣(不限量),怎么能用最少張的紙幣來兌換這張金額呢,顯然每次兌換應(yīng)該先從大額的紙幣兌換起,第一次選 100, 第二次還是選 100, 第三次選第二大的 50 元,每次都選小于剩余金額中的最大面額的紙幣,這樣得出的解一定是全局最優(yōu)解!時(shí)間復(fù)雜度無疑是線性的。

我們先來看幾道可以用貪心算法來求解的例題

貪心算法例題詳題

分糖果

  • 有 m 個(gè)糖果和 n 個(gè)孩子。我們現(xiàn)在要把糖果分給這些孩子吃,但是糖果少,孩子多(m < n),所以糖果只能分配給一部分孩子。每個(gè)糖果的大小不等,這 m 個(gè)糖果的大小分別是s1,s2,s3,……,sm。除此之外,每個(gè)孩子對(duì)糖果大小的需求也是不一樣的,只有糖果的大小大于等于孩子的對(duì)糖果大小的需求的時(shí)候,孩子才得到滿足。假設(shè)這 n 個(gè)孩子對(duì)糖果大小的需求分別是 g1,g2,g3,……,gn。那么如何分配糖果,能盡可能滿足最多數(shù)量的孩子呢?

求解:這道題如果用貪心來解解題思路還是比較明顯的,對(duì)于每個(gè)小孩的需求 gn,只要給他所有大小大于 gn 的糖果中的最小值即可,這樣就能把更大的糖果讓給需求更大的小孩。整個(gè)代碼如下:

  1. public class Solution { 
  2.     /** 
  3.      *  獲取能分配給小孩且符合條件的最多糖果數(shù) 
  4.      */ 
  5.     private static int dispatchCandy(int[] gList, int[] sList) { 
  6.         Arrays.sort(gList);     // 小孩對(duì)糖果的需求從小到大排列 
  7.         Arrays.sort(sList);     // 糖果大小從小到大排列 
  8.  
  9.         int maximumCandyNum = 0; 
  10.         for (int i = 0; i < gList.length; i++) { 
  11.             for (int j = 0; j < sList.length; j++) { 
  12.                 // 選擇最接近小孩需求的糖果,以便讓更大的糖果滿足需求更大的小孩 
  13.                 if (gList[i] <= sList[j]) { 
  14.                     maximumCandyNum++; 
  15.                     // 糖果被選中,將其置為-1,代表無效了 
  16.                     sList[j] = -1; 
  17.                     // 當(dāng)前小孩糖果已選中,跳出 
  18.                     break; 
  19.                 } 
  20.             } 
  21.         } 
  22.         return maximumCandyNum; 
  23.     } 
  24.  
  25.     public static  void main(String[] args) { 
  26.         // 小孩對(duì)糖果的需求 
  27.         int[] gList = {1,2,4,6}; 
  28.         // 糖果實(shí)際大小 
  29.         int[] sList = {1,2,7,3}; 
  30.         int result = dispatchCandy(gList, sList); 
  31.         System.out.println("result = " + result); 
  32.     } 

無重疊區(qū)間

  • 給定一個(gè)區(qū)間的集合,找到需要移除區(qū)間的最小數(shù)量,使剩余區(qū)間互不重疊。注意:可以認(rèn)為區(qū)間的終點(diǎn)總是大于它的起點(diǎn)。區(qū)間 [1,2] 和 [2,3] 的邊界相互“接觸”,但沒有相互重疊。
  • 示例 1: 輸入: [ [1,2], [2,3], [3,4], [1,3] ] 輸出: 1 解釋: 移除 [1,3] 后,剩下的區(qū)間沒有重疊。
  • 示例 2: 輸入: [ [1,2], [1,2], [1,2] ] 輸出: 2 解釋: 你需要移除兩個(gè) [1,2] 來使剩下的區(qū)間沒有重疊。
  • 示例 3: 輸入: [ [1,2], [2,3] ] 輸出: 0 解釋: 你不需要移除任何區(qū)間,因?yàn)樗鼈円呀?jīng)是無重疊的了。

區(qū)間重疊可以在生活中的很多場景里找到,比如任務(wù)調(diào)度,一個(gè)工人在一段時(shí)間內(nèi)需要完成多項(xiàng)任務(wù),每個(gè)任務(wù)需要完成的時(shí)間不同,如何在這段時(shí)間內(nèi)讓工人盡可能多地完成這些任務(wù)呢(任務(wù)與任務(wù)之間進(jìn)行的時(shí)間不能重疊,一個(gè)工人不可能在同一段時(shí)間內(nèi)同時(shí)進(jìn)行兩項(xiàng)任務(wù))

解題思路: 這道題我們分別用動(dòng)態(tài)規(guī)劃和貪心算法來解一下,以便對(duì)比一下兩者的時(shí)間復(fù)雜度,看下貪心算法是否在時(shí)間復(fù)雜度上更優(yōu)勝一些。

動(dòng)態(tài)規(guī)劃解法

首先為了方便求解,我們把每個(gè)區(qū)間按區(qū)間的起始點(diǎn)從小到大進(jìn)行排序,如圖示

 

接下來我們套用上篇中的說的動(dòng)態(tài)規(guī)劃解題四步曲來看看怎么用動(dòng)態(tài)規(guī)劃進(jìn)行求解。

1、 判斷是否可用遞歸來解

其實(shí)直觀地看上面我們排好序的各個(gè)區(qū)間,這不就是個(gè)組合嗎,每個(gè)區(qū)間要么選,要么不選,把所有的組合窮舉出來,再看哪個(gè)組合最符合題目中的條件,所以無疑是可以用遞歸的(組合用遞歸怎么解,強(qiáng)烈建議看下這篇文章)。

不過這題的組合有點(diǎn)特殊,前后兩個(gè)區(qū)間有條件限制,如果當(dāng)前區(qū)間與前一個(gè)區(qū)間重疊,則這兩者只能取其一(另一個(gè)需要剔除掉防止重疊),于是我們有如下思路:

定義兩個(gè)值, pre , cur ,分別代表前一個(gè)區(qū)間與當(dāng)前區(qū)間,需要進(jìn)行如下步驟

  • 比較前一個(gè)區(qū)間的終點(diǎn)與當(dāng)前區(qū)間的起始值
  • 如果前一個(gè)區(qū)間的終點(diǎn)小于當(dāng)前區(qū)間的起始值,代表兩區(qū)間不重疊,則將 pre 置為 cur, cur 置為 cur + 1, 開始接下來緊鄰的兩個(gè)區(qū)間的判斷(即重復(fù)步驟 1)。
  • 如果前一個(gè)區(qū)間的終點(diǎn)大于當(dāng)前區(qū)間的起始值,代表兩區(qū)間重疊,則 pre 不變, cur 置為 cur + 1 (即將 cur 對(duì)應(yīng)的區(qū)間移除),注意此時(shí)移除區(qū)間數(shù)要加 1, 然后開始接下來 pre,cur+1 區(qū)間的判斷(即重復(fù)步驟 1)。

注:首次區(qū)間遍歷我們定義 pre = -1,cur = 0

從以上的描述中可以很明顯地看到存在遞歸現(xiàn)象,于是我們寫出了如下代碼,關(guān)鍵代碼都作了詳細(xì)的注釋。

  1. public class Solution { 
  2.     // 區(qū)間類,包括起始值和終止值 
  3.     private  static  class Interval { 
  4.         int start; 
  5.         int end
  6.         Interval(int start, int end) { 
  7.             this.start = start; 
  8.             this.end = end
  9.         } 
  10.     } 
  11.  
  12.     private static Integer removeDuplicateIntervas(Interval[] intervals) { 
  13.         // 將區(qū)間按起始點(diǎn)由小到大進(jìn)行排序 
  14.         Arrays.sort(intervals, Comparator.comparingInt(a -> a.start)); 
  15.         // 首次遍歷從 -1,0 開始 
  16.         return removeSubDuplicate(-1, 0, intervals); 
  17.     } 
  18.  
  19.     private static Integer removeSubDuplicate(int pre, int cur, Interval[] intervals) { 
  20.         if (cur == intervals.length) { 
  21.             return  0; 
  22.         } 
  23.  
  24.         int notRemove = Integer.MAX_VALUE; 
  25.         if (pre == -1 || intervals[pre].end <= intervals[cur].start) { 
  26.  
  27.             /** 
  28.              * 如果是首次遍歷,或者 pre 區(qū)間的終點(diǎn)小于 cur 區(qū)間的起點(diǎn)(即區(qū)間不重疊), 
  29.              * 則 pre = cur; cur = cur+1 
  30.              */ 
  31.             notRemove = removeSubDuplicate(cur, cur+1, intervals); 
  32.         } 
  33.  
  34.         /** 
  35.          * 如果 pre 區(qū)間的終點(diǎn)大于 cur 區(qū)間的起點(diǎn),代表兩區(qū)間重疊,cur 指向后一個(gè)區(qū)間,即 cur = cur + 1 
  36.          * 代表 cur 被移除,所以需要加1(代表這個(gè)區(qū)間被移除了) 
  37.          */ 
  38.         int remove = removeSubDuplicate(pre, cur+1, intervals) + 1; 
  39.  
  40.         // 取兩者的較小值 
  41.         return Math.min(notRemove, remove); 
  42.     } 
  43.  
  44.     public static  void main(String[] args) { 
  45.         // 初始化區(qū)間 
  46.         Interval[] intervals = { 
  47.                 new Interval(1, 2), 
  48.                 new Interval(3, 5), 
  49.                 new Interval(4, 7), 
  50.                 new Interval(8, 10), 
  51.                 new Interval(9, 11) 
  52.         }; 
  53.         int result = removeDuplicateIntervas(intervals); 
  54.         System.out.println("result = " + result); 
  55.     } 

2、 分析在遞歸的過程中是否存在大量的重復(fù)子問題

怎么判斷是否存在大量的重復(fù)子問題,在一文學(xué)會(huì)動(dòng)態(tài)規(guī)劃解題技巧 我們提出一種方案,畫出遞歸樹 ,不過這題如果畫出遞歸樹比較麻煩,其實(shí)對(duì)于組合問題我們可以簡單分析一下,對(duì)于每個(gè)區(qū)間要么選,要么不選,我們以 1 代表該區(qū)間被選擇,以 0 代表該區(qū)間不選,則簡單考慮一下如下兩個(gè)組合

  1. 11010 
  2. 11001 

仔細(xì)看,紅框 部分,就是重復(fù)子問題!

 

可能有人會(huì)說這樣分析也有點(diǎn)難,那我再教大家一招,打印! 如圖示

 

在遞歸函數(shù)中打印出來,然后分析打印的規(guī)律

 

可以看到,確實(shí)存在著重復(fù)子問題,時(shí)間復(fù)雜度是多少呢,每個(gè)區(qū)間要么選,要么不選,共有兩個(gè)狀態(tài),如果有 n 個(gè)區(qū)間的話,就是 2^n,于是我們知道時(shí)間復(fù)雜度是 O(2^n),指數(shù)級(jí)!顯然無法接受

既然存在重復(fù)子問題,那我們進(jìn)入動(dòng)態(tài)規(guī)劃第三步

3、采用備忘錄的方式來存子問題的解以避免大量的重復(fù)計(jì)算(剪枝)

在以上的分析中基本我們看到,其實(shí)就是 pre, cur 有可能存在大量重復(fù),于是我們保存 pre, cur 對(duì)應(yīng)的中間結(jié)果,如下

  1. // 保存中間結(jié)果 
  2. private static HashMap<String, Integer> map = new HashMap(); 
  3. private static Integer removeSubDuplicate(int pre, int cur, Interval[] intervals) { 
  4.     String key = pre + "," + cur; 
  5.     if (map.get(key) != null) { 
  6.         return map.get(key); 
  7.     } 
  8.      
  9.     if (cur == intervals.length) { 
  10.         return 0; 
  11.     } 
  12.  
  13.     int notRemove = Integer.MAX_VALUE; 
  14.     if (pre == -1 || intervals[pre].end <= intervals[cur].start) { 
  15.         notRemove = removeSubDuplicate(cur, cur+1, intervals); 
  16.     } 
  17.  
  18.     int remove = removeSubDuplicate(pre, cur+1, intervals) + 1; 
  19.     int result = Math.min(notRemove, remove); 
  20.     map.put(key, result); 
  21.     return result; 

采用備忘錄的方式緩存子問題的中間結(jié)果后,時(shí)間復(fù)雜度直線下降,達(dá)到 O(n^2)(因?yàn)?pre, cur 兩個(gè)變量不斷往后移,即兩層循環(huán),所以是 O(n^2)) 。

4、改用自底向上的方式來遞推,即動(dòng)態(tài)規(guī)劃

我們定義 dp[i] 為 從 0 到 第 i 個(gè)區(qū)間的最大不重疊區(qū)間數(shù),于是我們得出了狀態(tài)轉(zhuǎn)移方程

  1. dp[i] = max{dp[j]} + 1, 其中 0 <=j < i 并且需要滿足一個(gè)條件 interval[i].start > interval[j].end,即保證 i, j 指向的區(qū)間不重疊。 

則最終的 dp[區(qū)間總個(gè)數(shù)-1] 即為最大的連續(xù)不重疊區(qū)間個(gè)數(shù),那么區(qū)間總個(gè)數(shù) - 最大的連續(xù)不重疊區(qū)間個(gè)數(shù)不就是最小要移除的區(qū)間數(shù)了,有了 dp 方程,寫起代碼來就快了,如下

  1. /** 
  2. * 判斷兩區(qū)間是否重疊, i 區(qū)間的起點(diǎn)比 j 區(qū)間的大, 如果 j 區(qū)間的終點(diǎn)比 i 區(qū)間的起點(diǎn)大,則重疊 
  3.  */ 
  4. private static boolean isOverlapping(Interval i, Interval j) { 
  5.     return j.end > i.start; 
  6.  
  7. /** 
  8.  * 動(dòng)態(tài)規(guī)劃求解 
  9.  */ 
  10. private static Integer removeSubDuplicateWithDP(Interval[] intervals) { 
  11.     // 將區(qū)間按起始點(diǎn)由小到大進(jìn)行排序 
  12.     Arrays.sort(intervals, Comparator.comparingInt(a -> a.start)); 
  13.  
  14.     int[] dp = new int[intervals.length]; 
  15.     Arrays.fill(dp, 0); 
  16.     dp[0]  = 1;    // 將 dp[0] 置為 1, 因?yàn)榫退闼械膮^(qū)間都重疊,則連續(xù)不重疊區(qū)間到少也為 1 
  17.  
  18.     int result = 1; 
  19.     for (int i = 1; i < intervals.length; i ++) { 
  20.         int max = 0; 
  21.         for (int j = 0; j < i; j ++) { 
  22.             if (!isOverlapping(intervals[i], intervals[j])) { 
  23.                 max = Math.max(dp[j], max); 
  24.             } 
  25.         } 
  26.         dp[i] = max + 1; 
  27.     } 
  28.     return intervals.length - dp[intervals.length - 1]; 

空間復(fù)雜度是多少,由于只有一個(gè) dp 一維數(shù)組,所以是 O(n),時(shí)間復(fù)雜度呢, 兩重循環(huán),所以是 O(n^2)??梢钥吹胶筒捎眠f歸+備忘錄的時(shí)間復(fù)雜度一樣,不過之前其實(shí)說了很多次,遞歸容易導(dǎo)致棧溢出,所以建議還是采用動(dòng)態(tài)規(guī)劃的方式來求解。

接下來重點(diǎn)來了,來看看如何用貪心算法來求解。首先要把各個(gè)區(qū)間按照區(qū)間的終點(diǎn)從小到大排列,如下

 

我們的思路與上文中的動(dòng)態(tài)規(guī)劃一樣,先求出最大不重疊子區(qū)間個(gè)數(shù),再用「區(qū)間總數(shù)-最大不重疊子區(qū)間個(gè)數(shù)」即為最小要移除的重疊區(qū)間數(shù)。

用貪心算法求最大不重大子區(qū)間個(gè)數(shù)步驟如下

  1. 選擇終點(diǎn)最小的區(qū)間,設(shè)置為當(dāng)前區(qū)間 cur 。
  2. 按區(qū)間終點(diǎn)從小到大尋找下一個(gè)與區(qū)間 cur 不重疊的區(qū)間,然后將此區(qū)間設(shè)置為當(dāng)前區(qū)間 cur(注意此時(shí)最大不重疊子區(qū)間個(gè)數(shù)要加1),不斷重復(fù)步驟 2, 直到遍歷所有的區(qū)間。

動(dòng)圖如下,相信大家看完動(dòng)圖會(huì)更容易理解

 

知道了解題思路,寫代碼就很簡單了

  1. /** 
  2.  * 貪心算法求解 
  3.  */ 
  4. private static Integer removeSubDuplicateWithGreedy(Interval[] intervals) { 
  5.     // 將區(qū)間終點(diǎn)由小到大進(jìn)行排序 
  6.     Arrays.sort(intervals, Comparator.comparingInt(a -> a.end)); 
  7.  
  8.     int cur = 0;            // 設(shè)置第一個(gè)為當(dāng)前區(qū)間 
  9.     int count = 1;      // 最大不重疊區(qū)間數(shù),最小為1 
  10.     for (int i = 1; i < intervals.length; i++) { 
  11.         // 不重疊 
  12.         if (intervals[cur].end < intervals[i].start) { 
  13.             cur = i; 
  14.             count++; 
  15.         } 
  16.     } 
  17.     // 總區(qū)間個(gè)數(shù)減去最大不重疊區(qū)間數(shù)即最小被移除重疊區(qū)間 
  18.     return intervals.length - count

時(shí)間復(fù)雜度是多少呢,只有一個(gè)循環(huán),所以是 O(n), 比起動(dòng)態(tài)規(guī)劃的 O(n^2),確實(shí)快了一個(gè)數(shù)量級(jí),簡單分析下為啥貪心算法這么快,由以上代碼可以看到,它只關(guān)心眼前的最優(yōu)解(選擇下一個(gè)與當(dāng)前區(qū)間不重疊的區(qū)間再依次遍歷,選完之后再也無需關(guān)心之前的區(qū)間了!)而動(dòng)態(tài)規(guī)劃呢,從它的 dp 方程(dp[i] = max{dp[j]} + 1)可以看出,對(duì)于每個(gè) i ,都要自底向上遍歷一遍 0 到 i 的解以求出最大值,也就是說對(duì)于動(dòng)態(tài)規(guī)劃的子問題而言,由于它追求的是全局最優(yōu)解,所以它有一個(gè)回溯(即自底向上求出所有子問題解的最優(yōu)解)的過程,回溯的過程中就有一些重復(fù)的子問題計(jì)算,而貪心算法由于追求的是眼前的最優(yōu)解,所以不會(huì)有這種回溯的求解,也就省去了大量的操作,所以如果可以用貪心算法求解,時(shí)間復(fù)雜度無疑是能上升一個(gè)量級(jí)的。

貪心算法適用場景

簡單總結(jié)一下貪心算法,它指的是每一步只選最優(yōu)的,并且期望每一步選擇的最優(yōu)解能達(dá)成全局的最優(yōu)解,說實(shí)話這太難了,因?yàn)橐话阋粋€(gè)問題的選擇都會(huì)影響下一個(gè)問題的選擇,除非子問題之間完全獨(dú)立,沒有關(guān)聯(lián),比如我們?cè)谖闹虚_頭說的湊零錢的例子, 如果一個(gè)國家的鈔票比較奇葩,只有 1,5,11 這三種面值的鈔票,如何用最少的鈔票湊出 15 呢,如果用貪心第一次選 11, 那之后只能選 4 張 1 了,即 15 = 1 x 11 + 4 x1。其實(shí)最優(yōu)解應(yīng)該是 3 張 5 元的鈔票,為啥這種情況下用貪心不適用呢,因?yàn)榈谝淮芜x了 11,影響了后面鈔票的選擇,也就是說子問題之間并不是獨(dú)立的,而是互相制約,互有影響的,所以我們選貪心的時(shí)候一定要注意它的適用場景。

再看三角形最短路徑和是否能用貪心算法求解

回過頭來看開頭的問題,三角形最短路徑和能否用貪心算法求解呢

先回顧一下這個(gè)題目:

 

如圖示,以上三角形由一連串的數(shù)字構(gòu)成,要求從頂點(diǎn) 2 開始走到最底下邊的最短路徑,每次只能向當(dāng)前節(jié)點(diǎn)下面的兩個(gè)節(jié)點(diǎn)走,如 3 可以向 6 或 5 走,不能直接走到 7。

如圖示:要求節(jié)點(diǎn) 2 到底部的最短路徑,它只關(guān)心節(jié)點(diǎn) 9, 10,之前層數(shù)的節(jié)點(diǎn)無需再關(guān)心!因?yàn)? 9,10 已經(jīng)是最優(yōu)子結(jié)構(gòu)了,所以只保存每層節(jié)點(diǎn)(即一維數(shù)組)的最值即可!

 

如果用貪心算法怎么求解

1、 第一步:由 2 往下走,由于 3 比 4 小,所以選擇 3

 

2、 第二步:由 3 往下走,由于 5 比 6 小,所以選擇 5

 

第三步: 從 5 往下走, 1 比 8 小,選擇 1

 

答案是 11 ,與動(dòng)態(tài)規(guī)劃得出的解一模一樣!那是否說明這道題可以用貪心算法求解?

答案是否定的!上面的解之所以是正確的,是因?yàn)檫@些數(shù)字恰好按貪心求解出來得出了全局最優(yōu)解,如果我們換一下數(shù)字,看看會(huì)如何

 

如圖示,如果數(shù)字換成如圖中所示,則按貪心得出的最短路徑是 66, 而實(shí)際上最短路徑應(yīng)該為 16,如下圖所示

 

為啥用貪心行不通呢,因?yàn)樨澬淖非蟮氖敲恳徊窖矍暗淖顑?yōu)解,一旦它作出了選擇,就會(huì)影響后面子問題的選擇,比如如果選擇了 3,就再也沒法選擇 7 了!所以再次強(qiáng)調(diào),一定要注意貪心的適用場景,子問題之間是否相互制約,相互影響!

總結(jié)

本文簡單講述了貪心算法的適用場景,相信大家對(duì)貪心的優(yōu)劣性應(yīng)該有了比較清晰的認(rèn)識(shí),貪心追求的是眼前最優(yōu)解(要最好的,就現(xiàn)在!)不管這次選擇對(duì)后面的子問題造成的影響,所以貪心求得解未必是全局最優(yōu)解,這就像我們做職業(yè)規(guī)劃一樣,千萬不可因?yàn)橐粫r(shí)的利益只考慮當(dāng)下的利益,要作出對(duì)長遠(yuǎn)的職業(yè)生涯能持續(xù)有益的選擇, 所以貪心的使用場景比較小,它是動(dòng)態(tài)規(guī)劃的特例,所以如果能用貪心來解的也都可以用動(dòng)態(tài)規(guī)劃來解。

責(zé)任編輯:武曉燕 來源: 碼海
相關(guān)推薦

2018-09-28 05:25:53

TopK算法代碼

2018-10-28 22:37:00

計(jì)數(shù)排序排序面試

2018-11-01 13:49:23

桶排序排序面試

2021-01-22 10:09:23

簡歷求職者面試

2020-03-30 17:20:54

B+樹SQL索引

2018-11-06 11:40:19

時(shí)間復(fù)雜度面試算法

2020-09-02 08:04:59

多線程互聯(lián)網(wǎng)高并發(fā)

2019-04-16 13:30:05

表達(dá)式求值數(shù)據(jù)結(jié)構(gòu)算法

2020-12-11 09:24:19

Elasticsear存儲(chǔ)數(shù)據(jù)

2019-01-08 15:11:50

最大值最小值算法

2020-09-24 14:40:55

Python 開發(fā)編程語言

2015-02-13 10:42:31

前端工具Dreamweaver

2020-04-16 08:22:11

HTTPS加解密協(xié)議

2022-03-14 10:14:43

底層系統(tǒng)Nacos

2018-11-09 09:34:05

面試Spring Clou底層

2019-08-29 09:49:50

2019-12-17 09:29:02

數(shù)據(jù)庫架構(gòu)分庫分表

2019-07-10 10:06:24

面試官三次握手四次揮手

2018-06-04 12:41:50

程序員貪心算法分析

2020-08-26 08:18:39

數(shù)據(jù)索引查詢
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)