日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法--将数组排成最小的数

發布時間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法--将数组排成最小的数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

將數組排成最小的數

  • 題目:輸入一個正整數的數組,將數組中所有數字拼接在一起排列成一個新的數,打印能拼接出來的所有數字中最小的一個,

  • 案例:輸入數組{12,4,55},則能打印出最小的數組是:12455

  • 首先還是最簡單的做法,我們求出數組中所有數字的全排列,然后將每個排列的情況拼接成一個新的數字,比較得到最小的數字情況。求數組的全排列問題我們在之前的文章:數據結構與算法–字符串的排列組合問題

  • 更具排列組合知識,n個數組共有n!個排列,當數組元素比較多的時候,時間復雜度會是一個非常大的數值,運行會非常慢,應該有更快的方案。

  • 常規優化:窮舉法是為了避開了一個選擇交換的過程,如果只有兩個元素,我們找出小的放到前面,那這個題目就轉成了一個找數組的排序規則的過程。數組根據這個排序規則排列成一個最小的數字。要確定排序規則,就需要比較兩個數字,也就是給出 m,n兩個數,我們需要確定一個排序規則判斷m,n那個應該在前面,這不是比較數字大小的問題。

  • 根據題目要求,兩個數字m,n,能拼出mn,nm兩個數字。

    • 如果mn < nm,那么我們應該輸出mn,也就是m應該在n前面,我們定義m 小于 n
    • 如果mn > nm,那么我們應該輸出nm,也就是n在m前,我們定義n 小于 m
    • 同樣mn = nm定義 m= n
    • 以上中 > < = 是我們數學意義上的比較,而大于,小于,等于,是我們自己定義的大小關系。
  • 那么我們接下來需要考慮的是怎么去拼接數字,當給出數字,m,n,我們直接計算的方式得到mn,nm的關系并不難。但是還有一個關鍵問題,當mn拼接后得到數字無法用int表達的時候,超過int類型的范圍那么我們就不能用普通的計算方式。有一個潛在的大數問題讓我必須用字符串的方式來計算。

  • 大數問題用字符串解決,字符串的比較問題,因為此處mn, nm 兩個數必然是兩個長度相等的字符串,那么比較他大小只需要按照字符串的大小比較規則就可以了。

  • 基于以上分析,我們可以先對數組中的所有數組進行快速排序

  • 排序規則用我們自定義規則,

  • 從小到大排序后,將所有數字依次拼接,就得到了最小值。

  • 經如上分析有如下代碼:

/*** 將數組中所有數據合并成一個數,求出能排成的最小數** @author liaojiamin* @Date:Created in 12:00 2021/6/8*/ public class FinMinNumber {public static String pringMinNumber(int[] array) {if (array == null || array.length <= 0) {return "";}if (array.length == 1) {return String.valueOf(array[0]);}String[] str = new String[array.length];for (int i = 0; i < array.length; i++) {str[i] = String.valueOf(array[i]);}quickSort(str, 0, str.length - 1);StringBuilder stringBuilder = new StringBuilder();for (String s : str) {System.out.print(s +", ");stringBuilder.append(s);}System.out.println();return stringBuilder.toString();}/*** 快排法,按從小到大排序字符串,字符串大小規則自定義* */public static String[] quickSort(String[] str, Integer left, Integer right) {if (left < right) {Integer temp = quickSortSwap(str, left, right);quickSort(str, left, temp - 1);quickSort(str, temp + 1, right);}return str;}public static Integer quickSortSwap(String str[], Integer left, Integer right) {if (left < right) {String position = str[left];while (left < right){while (left < right && myCompareTO(str[right], position) > 0) {right--;}if (left < right) {str[left] = str[right];left++;}while (left < right && myCompareTO(str[left], position) < 0) {left++;}if (left < right) {str[right] = str[left];right--;}}str[left] = position;}return left;}/*** 字符串大小規則比較,* ab > ba => a>b* ab == ba => a==b* ab<ba => a<b* */public static Integer myCompareTO(String a, String b){String ab = a+b;String ba = b+a;return ab.compareTo(ba);}public static void main(String[] args) {int[] str_1 = {12, 34, 1, 34, 777, 33, 99, 86, 56, 9};System.out.println(pringMinNumber(str_1));} }

后續問題

  • 如上實現方案中有兩個問題:

    • 第一我定義了一種新的比較兩個數的規則,但是這種規則是我們想出來的,并不是定理或者公
    • 第二我們定義的是比較兩個數的規則,但是用它來排序一個包含多個數字的數組,最終得到的是否是我們需要的的最小數字?
  • 那么以上兩點我們必須給出嚴格的數學證明,來確保方案的準確:

  • 第一,證明之前訂閱的比較規則有效性。一個比較規則有效,需滿足三個條件,自反性,對稱性,傳遞性

    • 自反性: 顯然,如果ab = ba, 那么 a等于b
    • 對稱性: 如果a 小于 b,則ab < ba, 所以ba > ab,因此b 大于 a
    • 傳遞性: 如果a 小于 b, 則 ab < ba。 假設a, b都是十進制表示時候,分別有1位,m位,有如下推斷
      如果有a 小于b
      ab = a * 10 m + b
      ba = b* 101 + a
      若 ab < ba
      有 a * 10 m + b < b* 101 + a
      a * 10 m - a < b* 101 - b
      a(10m-1) < b(101-1)
      a/(101-1) < b/(10m-1)
      同時如果有b 小于c,則bc < cb,同樣假設c十進制n位,與以上證明一致,得到
      b/(10m -1) < c(10n -1)
      綜上: a/(101-1) < b/(10m-1) < c(10n -1)
      a/(101-1) < c(10n -1)
      a(10n -1) < c(101-1)
      a * 10n + c < c * 101+a
      ac < ca
      a<c
  • 如上證明了這種比較規則滿足自反性,對稱性,傳遞性,是一種有效的比較規則,

  • 以下還需要證明根據如上規則將數組排序后,將數組中所有數字拼接起來得到的確實是最小值。

  • 略(太難了)

上一篇:數據結構與算法-- 數組中出現次數超過一半的數字(時間復雜度的討論)
下一篇:數據結構與算法–丑數

總結

以上是生活随笔為你收集整理的数据结构与算法--将数组排成最小的数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。