《剑指offer》第四十五题:把数组排成最小的数
// 面试题45:把数组排成最小的数 // 题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼 // 接出的所有数字中最小的一个。例如输入数组{3, 32, 321},则打印出这3个数 // 字能排成的最小数字321323。 #include "cstdio" #include <string> #include <algorithm> #pragma warning(disable:4996) //忽略安全性较低的vs警告 int compare(const void* strNumber1, const void* strNumber2); // int型整数用十进制表示最多只有10位 const int g_MaxNumberLength = 10; char* g_StrCombine1 = new char[g_MaxNumberLength * 2 + 1]; char* g_StrCombine2 = new char[g_MaxNumberLength * 2 + 1]; void PrintMinNumber(const int* numbers, int length) { if (numbers == nullptr || length <= 0) return; //将数组转换为字符串, 二维数组注意** char** strNumber = (char**)(new int[length]); for (int i = 0; i < length; ++i) { strNumber[i] = new char[g_MaxNumberLength + 1]; sprintf(strNumber[i], "%d", numbers[i]); } qsort(strNumber, length, sizeof(char*), compare); for (int i = 0; i < length; ++i) printf("%s", strNumber[i]); printf("\n"); for (int i = 0; i < length; ++i) //记得删除创建的二维数组 delete[] strNumber[i]; delete[] strNumber; } // 如果[strNumber1][strNumber2] > [strNumber2][strNumber1], 返回值大于0 // 如果[strNumber1][strNumber2] = [strNumber2][strNumber1], 返回值等于0 // 如果[strNumber1][strNumber2] < [strNumber2][strNumber1], 返回值小于0 int compare(const void* strNumber1, const void* strNumber2) { //[strNumber1][strNumber2] strcpy(g_StrCombine1, *(const char**)strNumber1); strcat(g_StrCombine1, *(const char**)strNumber2); //[strNumber2][strNumber1] strcpy(g_StrCombine2, *(const char**)strNumber2); strcat(g_StrCombine2, *(const char**)strNumber1); return strcmp(g_StrCombine1, g_StrCombine2); }
// ====================测试代码==================== void Test(const char* testName, int* numbers, int length, const char* expectedResult) { if (testName != nullptr) printf("%s begins:\n", testName); if (expectedResult != nullptr) printf("Expected result is: \t%s\n", expectedResult); printf("Actual result is: \t"); PrintMinNumber(numbers, length); printf("\n"); } void Test1() { int numbers[] = { 3, 5, 1, 4, 2 }; Test("Test1", numbers, sizeof(numbers) / sizeof(int), "12345"); } void Test2() { int numbers[] = { 3, 32, 321 }; Test("Test2", numbers, sizeof(numbers) / sizeof(int), "321323"); } void Test3() { int numbers[] = { 3, 323, 32123 }; Test("Test3", numbers, sizeof(numbers) / sizeof(int), "321233233"); } void Test4() { int numbers[] = { 1, 11, 111 }; Test("Test4", numbers, sizeof(numbers) / sizeof(int), "111111"); } // 数组中只有一个数字 void Test5() { int numbers[] = { 321 }; Test("Test5", numbers, sizeof(numbers) / sizeof(int), "321"); } void Test6() { Test("Test6", nullptr, 0, "Don't print anything."); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); return 0; }
分析:快排算法。
class Solution { public: string PrintMinNumber(vector<int> numbers) { int length = (int) numbers.size(); string strNumber = ""; sort(numbers.begin(), numbers.end(), compare); for (int i = 0; i < length; ++i) strNumber += to_string(numbers[i]); return strNumber; } static bool compare(int strNumber1, int strNumber2) { string g_StrCombine1 = ""; string g_StrCombine2 = ""; //[strNumber1][strNumber2] g_StrCombine1 += to_string(strNumber1); g_StrCombine1 += to_string(strNumber2); //[strNumber2][strNumber1] g_StrCombine2 += to_string(strNumber2); g_StrCombine2 += to_string(strNumber1); return g_StrCombine1 < g_StrCombine2; } };