問題描述:輸入乙個正整數陣列,將它們連線起來排成乙個數,輸出能排出的所有數字中最小的乙個。例如輸入陣列,則輸出這兩個能排成的最小數字32132。請給出解決問題的演算法,並證明該演算法。
思路:先將整數陣列轉為字串陣列,然後字串陣列進行排序,最後依次輸出字串陣列即可。這裡注意的是字串的比較函式需要重新定義,不是比較a和b,而是比較ab與 ba。如果ab < ba,則a < b;如果ab > ba,則a > b;如果ab = ba,則a = b。比較函式的定義是本解決方案的關鍵。這道題其實就是希望我們能找到乙個排序規則,根據這個規則排出來的陣列能排成乙個最小的數字。
證明:為什麼這樣排個序就可以了呢?簡單證明一下。根據演算法,如果a < b,那麼a排在b前面,否則b排在a前面。可利用反證法,假設排成的最小數字為******,並且至少存在一對字串滿足這個關係:a > b,但是在組成的數字中a排在b前面。根據a和b出現的位置,分三種情況考慮:
(1)***xab,用ba代替ab可以得到***xba,這個數字是小於***xab,與假設矛盾。因此排成的最小數字中,不存在上述假設的關係。
(2)ab***x,用ba代替ab可以得到ba***x,這個數字是小於ab***x,與假設矛盾。因此排成的最小數字中,不存在上述假設的關係。
(3)a***xb,這一步證明麻煩了一點。可以將中間部分看成乙個整體ayb,則有ay < ya,yb < by成立。將ay和by表示成10進製數字形式,則有下述關係式,這裡a,y,b的位數分別為n,m,k。
關係1: ay < ya => a * 10^m + y < y * 10^n + a => a * 10^m - a < y * 10^n - y => a( 10^m - 1)/( 10^n - 1) < y
關係2: yb < by => y * 10^k + b < b * 10^m + y => y * 10^k - y < b * 10^m - b => y < b( 10^m -1)/( 10^k -1)
關係3: a( 10^m - 1)/( 10^n - 1) < y < b( 10^m -1)/( 10^k -1) => a/( 10^n - 1)< b/( 10^k -1) => a*10^k - a < b * 10^n - b =>a*10^k + b < b * 10^n + a => a < b
這與假設a > b矛盾。因此排成的最小數字中,不存在上述假設的關係。
綜上所述,得出假設不成立,從而得出結論:對於排成的最小數字,不存在滿足下述關係的一對字串:a > b,但是在組成的數字中a出現在b的前面。從而得出演算法是正確的。
**一:利用指標。
[html]view plain
copy
#include
<
iostream
>
#include <
string.h
>
using namespace std;
const int g_maxnumberlength=10
; char* g_strcombine1
=new
char[g_maxnumberlength*2+1];
char* g_strcombine2
=new
char[g_maxnumberlength*2+1];
int compare(const void* strnumber1, const void* strnumber2)
void printminnumber(int *numbers, int length)
qsort(strnumbers, length, sizeof(char*), compare);
for(i=0
; i<
length
; i++)
cout<
<
strnumbers
[i];
cout<
<
endl
; for(i=0
; i<
length
; i++)
delete strnumbers[i];
delete strnumbers;
} void main()
**二:利用string類。
[cpp]view plain
copy
#include
#include
#include
#include
using
namespace
std;
bool
compare(
const
string& str1,
const
string &str2)
void
comarraymin(
int*parray,
intnum)
sort(pstrarray, pstrarray+num, compare);
for(i=0; i
cout<
cout<
delete
pstrarray;
} void
main()
感謝:
面試題33 把陣列排成最小的數
題目 輸入乙個正整數陣列,把陣列裡所有數字拼接起來排成乙個數。列印能拼接處的所有數字鐘最小的乙個。例如輸入陣列,則列印出這3個數字能排成的最兇啊數字321323.思路 1,傳統 陣列全排列,再排序 2,定義排序規則,將整數轉化成字元陣列,兩個字元陣列比較大小的比較函式要重新定義,a b 與 b a ...
面試題37 把陣列排成最小的數
題目 輸入乙個正整數陣列,把陣列裡所有數字拼接起來排成乙個數,列印能拼接出的所有數字中最小的乙個。邊界條件及異常 陣列為空 思路 這題可以需要建立對任意兩個數自己的比較規則。然後根據這個規則進行排序即可。如果是單位數,顯然小的在前。如果是32和321,結合後有32321和32132兩種結果,比較這兩...
面試題 把陣列排成最小的數(C )
輸入乙個正整數陣列,把陣列裡所有數字拼接起來排成乙個數,列印能拼接出的所有數字中最小的乙個。例如輸入陣列,則打出這3個數字能排成的最小數字321323。這個題目最直接的做法應該是先求出這個陣列中所有數字的全排列,然後把每個排列拼起來,最後求出拼起來的數字的最大值,這裡不過多敘述。根據排列組合的知識,...