【剑指offer】面试题45:把数组排成最小的数

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

这一题有个解法,相比于原书上的方法,更好理解、更加简单!有现成的工具当然要用现成的,抵制重复造轮子的行为。

  • 解题思路:
    对整个数组排序,任意mn和nm比较,小的放前面,大的放后面,然后按顺序输出整个数组就是答案。

  • 几个注意点:
    1.数字拼接,如mn需要注意是否会超出int范围边界,隐形大数问题
    大数问题的解决方法:数字转字符串,这里用to_string函数实现。

  • 解题步骤:
    自己自定义一个cmp函数,用sort完成数组的排序即可。

【考点】 排序 大数问题

class Solution {
public:
	string PrintMinNumber(vector<int> numbers) 
	{
		string answer = "";
		sort(numbers.begin(), numbers.end(), cmp);
		for(int i = 0; i < numbers.size(); i++)
		{
			answer += to_string(numbers[i]);
		}
		return answer;
    }
    // 然后自定义这个cmp函数
    static bool cmp(int a, int b)
    {
        string A = "";
        string B = "";
        
        A += to_string(a);
        A += to_string(b);
        
        B += to_string(b);
        B += to_string(a);
        
        return A<B;
    }
};

题解结束,下面是查缺补漏环节。

一、关于to_string()
使用to_string函数的头文件为<string>

二、关于sort()
使用sort函数的头文件为<algorithm>
形式:sort(first_pointer, first_pointer+n, cmp)

三、关于sort()里的cmp:
1.可自定义cmp函数,如本题
2.用标准库<functional>
equal_to<Type>、not_equal_to<Type>
降序greater<Type> 、greater_equal<Type>
升序less<Type> 、less_equal<Type>
3.重载结构体或类的比较运算符,可省略cmp

四、关于equal_to<Type>
手动抄下官方示例代码练练手,有点精致的:

#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
	vector <double> v1, v2, v3(6);
	vector <double>::iterator Iter1, Iter2, Iter3;
	
	int i;
	for ( i = 0; i <= 5; i += 2 )
	{
		v1.push_back( 2.0 * i );
		v1.push_back( 2.0 * i + 1.0 );
	}

	int j;
	for ( j = 0; j <= 5; j += 2 )
	{
		v2.push_back( - 2.0 * j );
		v2.push_back( 2.0 * j + 1.0 );
	}

	cout << "The vector v1 = ( ";
	for (Iter1 = v1.begin(); Iter1 != v1.end(); Iter1++)
		cout << *Iter1 << " ";
	cout << ")" << endl;

	cout << "The vector v2 = ( ";
	for (Iter2 = v2.begin(); Iter2 != v2.end(); Iter2++)
		cout << *Iter2 << " ";
	cout << ")" << endl;

	// Testing for the element-wise equality between v1 & v2
	transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), equal_to<double>());

	cout << "The result of the element-wise equal_to comparison\n"
		<< "between v1 & v2 is: ( ";
	for (Iter3 = v3.begin(); Iter3 != v3.end(); Iter3++)
		cout << *Iter3 << " ";
	cout << ")" << endl;

	return 0;
}

Output

The vector v1 = ( 0 1 4 5 8 9 )
The vector v2 = ( -0 1 -4 5 -8 9 )
The result of the element-wise equal_to comparison
between v1 & v2 is: ( 1 1 0 1 0 1 )

https://docs.microsoft.com/zh-cn/cpp/standard-library/equal-to-struct?view=vs-2017

五、关于transform()
在看equal_to<Type>文档的时候,发现它是用transform()当例子的,那就看下transform,头文件在<algorithm>
官方:将指定的函数对象应用于源范围中的每个元素或两个源范围中的元素对,并将函数对象的返回值复制到目标范围。
很明显是一个重载,因为不确定是一个源范围还是两个源范围。

template<class InputIterator, class OutputIterator, class UnaryFunction>
OutputIterator transform(
    InputIterator first1,
    InputIterator last1,
    OutputIterator result,
    UnaryFunction func );

template<class InputIterator1, class InputIterator2, class OutputIterator, class BinaryFunction>
OutputIterator transform(
    InputIterator1 first1,
    InputIterator1 last1,
    InputIterator2 first2,
    OutputIterator result,
    BinaryFunction func );
点赞