面試題45:把陣列排成最小的數。輸入乙個正整數陣列,把陣列裡所有數字拼接起來排成乙個數,列印能拼接出的所有數字中最小的乙個。如,輸入,則列印出這三個數字能排出的最小數字321323。
這道題最簡單的解法是先求出陣列中所有數字的全排列,然後把每個排列都拼起來,最後求出拼起來的數字的最小值,n個數字總共有n!個排列,效率低。
我們需要找到乙個排序規則,陣列根據這個排序規則能排成乙個最小的數字,我們需要比較兩個數字,確定乙個規則用於判斷兩個數哪個應該排在前面。
兩個數字m和n能拼接成數字mn和nm,哪個數字小就應該選擇哪個作為數字m和n拼接後的結果。在拼接時,可能會溢位,因此這是乙個隱含的大數問題,將數字轉化為字串可以解決:
#include
#include
#include
#include
using
namespace std;
bool
compare
(const string& s1,
const string& s2)
void
printminnum
(int
* nums,
int length)
vector svec;
for(
int i =
0; i < length;
++i)
sort
(svec.
begin()
, svec.
end(
), compare)
;for
(const string& s : svec)
cout << endl;
}int
main()
;printminnum
(nums,
sizeof
(nums)
/sizeof
(*nums));
}
以上演算法使用sort函式,排序的時間複雜度為o(nlogn)。
以下是不用標準庫函式sort的版本:
#include
#include
#include
#include
using
namespace std;
bool
compare
(const string& s1,
const string& s2)
void
quicksort
(vector
& svec,
int beg,
int end)
int mid =
(beg + end)/2
, small = beg -1;
uniform_int_distribution<
int>
u(beg, end)
; default_random_engine e
(time(0
));unsigned rand =
u(e)
; cout << rand << endl;
swap
(svec[rand]
, svec[end]);
int l = beg;
while
(l < end)
++l;
}swap
(svec[small +1]
, svec[end]);
quicksort
(svec, beg, small)
;quicksort
(svec, small +
2, end);}
void
printminnum
(vector<
int>
& ivec)
quicksort
(svec,
0, svec.
size()
-1);
for(string& s : svec)
cout << endl;
}int
main()
;printminnum
(nums)
;}
接下來驗證演算法的正確性,這需要三個條件(以下條件中兩個字母連在一起不表示乘法,表示兩個數字拼接成的數字結果):
1.自反性:aa=aa,所以a=a。
2.對稱性:若aab,因此b>a。
3.傳遞性:如果am+b,ba=bx10l+a。
劍指offer 學習筆記 陣列
int getsize int data intmain cout sizeof data endl int p data cout sizeof p endl cout getsize data endl return0 以上 輸出為20 4 4,sizeof data 求的是陣列大小,p雖然和陣...
劍指offer學習筆記
筆記主要記錄方法和知識點 知識點1 負數與補碼 乙個參考 知識點2 移位操作 右移 變小 按位 操作 知識點3 0xffffffff表示32位 1 o logn 的方法 非遞迴的快速冪,用到二進位制表示。在迴圈內注意base base。兩個指標等間距一起走。想明白斷開鍊錶這個事情,相當於操作是在原有...
劍指offer 陣列
資料是最簡單的資料結構,它佔據一塊連續的記憶體並按照順序儲存資料。建立陣列時,首先指點陣列的容量大小,然後根據大小分配記憶體。缺點 空間效率不高。經常有空閒的區域滅有得到充分利用。優點 時間效率很高。可以根據時間效率高的特點,來實現簡單的雜湊表 把陣列的下標設為雜湊表的鍵值,陣列中的每乙個數字設為雜...