首發於 樊浩柏科學院
問題敘述:將一個非負元素數組中的全部元素排列組合在一塊兒,找出值最大的那個排列狀況。例如 [0, 9, 523, 94, 10, 4],排列組合後值最大數爲:9945234100。html
本文廢話較多,能夠直接跳轉到 編碼實現 部分。面試
這是我遇到的一道筆試題。首次碰見我也是很懵,當時個人第一感受就是排序,可是沒有及時理清裏面的規律,致使後面並無解答出此題。算法
該問題描述很簡單,也給出了測試用例,需求很明白。可是還須要注意問題背後隱藏的一些問題。編程
可肯定輸入的狀況大體爲:數組
面試時請教了一下面試官,面試官的思路:函數
最簡單辦法就是枚舉全部可能的排列組合狀況,而後求排列組合後的最大值;再就是尋找組合的規律,知足什麼條件的元素排列在前。
固然這只是面試官提供的一些解決思路,付諸於實踐還須要探索。在複試前的一天晚上我再次翻出這個問題,並找到了一些思路。測試
就拿問題中的用例 [0, 9, 523, 94, 10, 4] 來講,須要找出的結果爲:9,94,523,4,10,0(爲了方便說明,用」,「分割了數組元素)。ui
先將複雜問題簡單化處理,首先嚐試使用 排序算法 來分析過程。分析 9 和 94 的排列,爲何 9 排列在 94 前?[那是由於這 2 個數存在 2 種排列狀況,既_ 9_94_ 和_ 9_49_,很明顯 9_94 排列大於 9_49 排列,因此須要將 9 排列在 94 前,反之則須要交換元素位置]()。若是採用這樣規則處理,是在 2 個元素之間進行枚舉排列狀況,且單次枚舉狀況限定在了 2 種,下降了問題的複雜程度並易於編碼實現,後續能夠直接使用排序方法來屢次重複這種 2 個元素之間的單次枚舉動做。編碼
說明:符號「_」爲佔位符,表示該位置可能還存在其餘元素,但不影響當前兩個元素的先後排列順序。後續出現該符號將再也不說明。spa
總之,我認爲該問題是排序問題的一個變種狀況,同排序問題不一樣的是 比較規則。這裏不是直接比較 2 個元素值大小,而是比較 2 個元素排列組合後值的大小。
通過上述分析,問題規律已經掌握清楚,這裏整理出實現的思路。
使用冒泡排序來講明上述用例的排序過程。
本問題的排序比較規則能夠描述爲:假設參與比較的兩個元素爲 A、B(初始時 A 在 B 前,排序結果從左至右爲由大到小),比較時若是排列 A_B 小於排列 _B_A_,A 和 B 則交換位置,反之不交換。
/** * 比較規則 * @param string $a * @param string $b * @return int */ function cmp($a, $b) { if ($a == $b) { return 0; } return $a . $b > $b . $a ? -1 : 1; }
/** * 冒泡排序 * @param array $Arr 待排序數組 * @return array */ function bubble_sort(array $Arr) { $length = count($Arr); if ($length < 2) { return $Arr; } for ($i = 1, $change = true; $i <= $length && $change; $i++) { $change = false; for ($j = $length - 1; $j > $i - 1; $j--) { if (cmp($Arr[$j - 1], $Arr[$j]) > 0) { $temp = $Arr[$j - 1]; $Arr[$j - 1] = $Arr[$j]; $Arr[$j] = $temp; $change = true; } } } return $Arr; } /** * 尋找非零元素數組中全部元素排列組合後的最大值 * @param array $Arr 待排序數組 * @param string $method 排序方法 * @return mixed */ function array_form_max_str(array $Arr, $method = 'bubble') { //參數校驗 if (!is_array($Arr)) return false; foreach ($Arr as $value) { if ($value < 0) return false; } //排序算法 switch ($method) { case 'quick' : usort($Arr, "cmp"); //快速排序 break; case 'bubble' : $Arr = bubble_sort($Arr); //冒泡排序 break; default : break; } //拼接 return implode('', $Arr); }
因爲 PHP 中 sort 排序函數採用快速排序算法,這裏直接使用之。
/** * 尋找非零元素數組中全部元素排列組合後的最大值 * @param array $Arr 待排序數組 * @param string $method 排序方法 * @return mixed */ function array_form_max_str(array $Arr, $method = 'quick') { //參數校驗 if (!is_array($Arr)) return false; foreach ($Arr as $value) { if ($value < 0) return false; } //排序算法 switch ($method) { case 'quick' : //快速排序 usort($Arr, "cmp"); break; case 'bubble' : $Arr = bubble_sort($Arr); //冒泡排序 break; default : break; } //拼接 return implode('', $Arr); }
這裏只對快速排序方法使用 2 組測試用例並列舉以下。
$Arr = [20,913,223,91,20,3]; echo '數組爲[', implode(',', $Arr), ']', PHP_EOL; echo '最大排列組合爲:', array_form_max_str($Arr), PHP_EOL;
//第1組用例 數組爲[0,9,523,94,10,4] 最大排列組合爲:9945234100 //第2組用例 數組爲[20,913,223,91,20,3] 最大排列組合爲:9191332232020
通過深刻分析問題的本質,也使得我對與排序算法有了更深刻的認識,更算是一個鞏固。同時,正是因爲我嘗試着去解決這個問題,才使得我在後面的複試環節中面試官再次提出相同問題時,給出了一個滿意的解決方案。
相關文章 »