面试题45-把数组排成最小的数

题目

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

解题思路

遇到这个题,全排列当然可以做,但是时间复杂度为O(n!)。在这里我们自己定义一个规则,对拼接后的字符串进行比较。

排序规则如下:

若ab > ba 则 a 大于 b,
若ab < ba 则 a 小于 b,
若ab = ba 则 a 等于 b;

根据上述规则,我们需要先将数字转换成字符串再进行比较,因为需要串起来进行比较。比较完之后,按顺序输出即可。

C++实现

class Solution {
public:
	string PrintMinNumber(vector<int> numbers) {
		int length = numbers.size();
		if (length == 0) {
			return "";
		}
		sort(numbers.begin(), numbers.end(), cmp);
		string res;
		for (int i = 0; i < length; i++) {
			res += to_string(numbers[i]);
		}
		return res;
	}
private:
	// 升序排序
	static bool cmp(int a, int b) {
		string A = to_string(a) + to_string(b);
		string B = to_string(b) + to_string(a);
		return A < B;
	}
};

剑指Offer书上实现

class solution
{
public:
	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(int *numbers, int length)
	{
		if (!numbers || !length)
			return;
		char **strnumbers = (char**)(new int[length]);  //char** strnumbers = new char*[前面一维数组的长度]
		for (int i = 0; i < length; ++i)
		{
			strnumbers[i] = new char[g_maxnumberlength + 1];
			sprintf(strnumbers[i], "%d", numbers[i]);
		}
		qsort(strnumbers, length, sizeof(char*), compare);
		for (int i = 0; i < length; ++i)
			printf("%s", strnumbers[i]);
		printf("/n");
		for (int i = 0; i < length; ++i)
			delete[]strnumbers[i];
		delete[] strnumbers;
		
	}
private:
int compare(const void *strnumber1, const void * strnumber2)
	{
		strcpy(g_strcombine1, *(const char**)strnumber1);
		strcat(g_strcombine1, *(const char**)strnumber2);
		strcpy(g_strcombine2, *(const char**)strnumber2);
		strcat(g_strcombine2, *(const char**)strnumber1);
		return strcmp(g_strcombine1, g_strcombine2);
	}
};

  1. 时间复杂度:O(nlogn),和qsort的时间复杂度相同
  2. 空间复杂度:O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值