剑指offer--把数组排成最小数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Hanani_Jia/article/details/82499088

题目描述

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

 

因为我在刷剑指offer的时候是按通过率来刷的,先把通过率高的题刷了,虽然经常遇到没思路的或者在写程序的时候遇到一些大大小小的问题但是大部分都能解决,这个题目让我遇到了很多问题,并且看了代码之后还有很多问题。

  本来不想把自己的代码贴出来,想了想还是拿出来,错的很离谱。

class Solution {

public:

string PrintMinNumber(vector<int> numbers) {

int length = numbers.size();//求数组长度

//排一下序

int i = 0;

int j = 0;

for (; i < length; i++)

{

for (j = 0; j < length - i - 1; j++)

{

if (numbers[j]>numbers[j + 1])

{

int temp = numbers[j];

numbers[j] = numbers[j + 1];

numbers[j + 1] = temp;

}

}

}

int num = 0;

for (i = 0; i < length; i++)

{

num = num + numbers[i] * pow(10, length - 1 - i);

}

return num;

}

};

  我犯了最大的错误就是返回的是int类型的数据,题目中写着string类型,这导致我在编译的时候都没有通过,第二个大问题就是我想的简单了,我想的是把数组排一下序小的在最前边,大的放后边就行,这当时还是因为自己想成了int类型,所以想的是第一个数肯定要乘10的次方大一些,后边的乘的小一些,所以就简单的排序了。这个很好理解,假如现在有两个数字11和2,如果2在前边得到的数字是211,而11在前边就是112,那肯定是112大,所以不能是单纯的让两个数字来排序。

  所以我们要从一点一点来修改自己的程序,首先我们要做到的是把我们的int类型转换成string类型。这里我们用到的函数是to_string

to_string支持很多类型转换成string类型的函数,这种类型的函数还有很多,这里就不过多的介绍了,我们在程序里边直接使用就行。

 这里重要的是我们的排序函数,我们不能是单纯的比较大小来排序。这里我们要介绍的sort函数,先把大家提交的通过的代码贴出来,如果能很好的理解的就没必要看我下边的了。

/*对vector容器内的数据进行排序,按照 将a和b转为string后

若 a+b<b+a  a排在在前 的规则排序,

如 2 21 因为 212 < 221 所以 排序后为 21 2

to_string() 可以将int 转化为string

*/ class Solution {

public:

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;

}

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;

}

};

因为我不是很理解sort函数的用法所以这里花费了很多的时间去看明白这个程序。这里就给大家简单的介绍一下sort函数的用法

我们在cplusplus网站上可以查一下sort的用法,这里有一个默认用法和一个扩展的用法,可以看出来两种用法传入的参数个数是不相同的,默认的函数我们传入了两个参数,通过英文也能看出来他的两个参数一个是要数组的起始位置,一个是终止位置。这里我们拿一下cplusplus上边的例子可以看一下。

可以看出来这里的第一个参数就是我们的数组的begin也就是起始位置,第二个位置是起始位置+4,所以排序过后只有前4个数字进行了排序。所以我们可以通过这两个参数来控制我们想要排序的部分。这个很好理解。

  但是扩展之后的sort虽然不是很复杂但是不太好理解。

这是官网对参数部分的介绍,这里我们看cmp,他说这是一个二进制的函数他接受范围内的两个参数也就是你在比较的时候操作的两个数字,并且这个函数的返回类型必须是bool型的,返回值的指示作为第一个参数传递的元素是否被看成他它定义的特定严格弱排序中位于第二个参数之前。这里其实我认为就是你返回一个bool值如果是说你返回了true说明这是真的sort就不操作了,如果是假的sort就要将这两个数字的位置进行一下交换,并且这个函数是不能在函数内部对我们传入的参数进行修改的,这里就算解开了我的疑惑,明明我们在调用这个函数的时候是没有参数传入的,但是他的函数确实需要两个参数并且还没有报错。原因就在这里。

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;

}

这里就是我们让相邻的两个数组进行一下组合,A代表的是a在前边也就是第一个参数在前边b在后边第二个参数在后边,B是两者相反b在前边a在后边,然后return A<B 如果A是小于b的那说明a在前边是对的,那就返回的是真值,这时候sort是不需要做任何操作,如果是我们的B>A那就会返回false这时候sort就会将两个比较的参数交换一下位置。排序之后需要做的就是把整个数组串成一个字符串就可以了。

  本来在这篇博客下给sort函数在STL中的底层实现进行了一个介绍,介绍完之后发现,完全可以把对sort的底层介绍单独成一个博客,所以就给分开了。如果大家想了解的可以去看我的另一篇博客。https://blog.csdn.net/Hanani_Jia/article/details/82498469

设一个有序的单链表中有n个结点,现要求插入一个新结点后使得单链表仍然保持有序,则该操作的时间复杂度为()。

A.O(log2n)

B.O(1)

C.O(n2)

D.O(n)

 今天的选择题比较简单,这里我们要做的是往有序的单链表中插入一个数据,这里我想说就是如果我们现在不是单链表的话如果是数组我们就可以采用二分法,来实现,二分法最最差的复杂度是O(log2),因为假如我们数组的长度是32,二分二分一直二分到5次的时候也就不能再分了,总有分到头的那一天吧,最差的次数就是log2了。所以二分法的时间复杂度是O(log2)。对于单链表的排序,使用快速排序或者说插入排序一类的也不是不能实现,但是很多题好像并没有考虑这些事情。

 

 

猜你喜欢

转载自blog.csdn.net/Hanani_Jia/article/details/82499088