目录
1. 错解 ❌
1.1 错解1:
看到这道题之后,首先的一个思路就是依次比较 相邻的两个数,此时需要注意考虑 这两位数之间含 0 的一个情况,,此时可分为四种情况,在其中一种(两个数都不含0的)情况里还需要考虑两个数都是个位数还是 多位数字,然后进行判定。
错解1错误原因主要有以下几点:
1. 只考虑到相邻的两个点,未考虑到其前面或后面的对其影响。比如[9,34,8]
第一次判断: 9 34,由于34 > 9 但由于是个位数字,此时组成 934
第二次判断: 34 8 由于34 > 8但由于是个位数字,此时组成 8934 ❌
2. 两个数都不含0的)情况里还需要考虑两个数都是个位数还是 多为数字,即使考虑也需要考虑个位数字与多位数字开头的比较,比如[9,34,2]
第一次判断: 9 34,由于34 > 9 但由于是个位数字,此时组成 934
第二次判断: 34 2 由于34 > 2但由于是个位数字,此时组成2934 ❌
1.2 错解2
在第一个想法 运行错误时,此时想到了排序算法,按照从大到小的顺序进行排序,此时只针对哪些首位数字都不相同的多位数字有用,为什么这样讲?可以想一下若是有一个位数字 9 出现,肯定会考虑将其放在最前面,所以经过排序,9 是位于高位数的后面,此时组成的最大数是错误的。
1.3 错解CODE
// 贪心:根据当前局部最优解获取全局最优解,并且当前的状态受之前影响,此状态不会影响后面结果
/* 思路:只需要判断当前结点和其前一个结点的大小关系:
1. 若 两者之间没有一个 含有 0 的数字将其放在前面
2. 两者都含 0 就将 大数放在前面即可
弊端:该解法容易忽略 即使两者都不含 0 以及两者都是多位数字,两者之间位数不同此时还需要比较较短位数和另一个数进行比较,判断短位的最后一位和较长一位的相同位置的大小进行比较,然后再选择其中一位。
int n=nums.size();
string s=to_string(nums[0]);
for(int i=1;i<n;i++){
printf("第%d次:s=%s, nums[i-1]=%d ;nums[i]=%d \n",i,s.c_str(),nums[i-1],nums[i]);
if(nums[i-1]%10==0&&nums[i]%10==0) //两者都喊零
{
if(nums[i-1]>=nums[i])
s+=to_string(nums[i]);
else
s=to_string(nums[i])+s;
}
else if(nums[i-1]%10!=0&&nums[i]%10!=0){//两者都不含 0,还需要判断 位数
int max_num=max(nums[i-1],nums[i]);
int min_num=min(nums[i-1],nums[i]);
if(max_num<10||min_num>9) // 说明都是个位数字
{
if(nums[i-1]>=nums[i])
s+=to_string(nums[i]);
else
s=to_string(nums[i])+s;
}
else if(max_num>9&&min_num<10)
{
if(nums[i-1]==min_num)
s=s+to_string(max_num);
else
s=to_string(min_num)+s;
}
}
else if(nums[i-1]%10!=0&&nums[i]%10==0){//
s+=to_string(nums[i]);
}
else
s=to_string(nums[i])+s;
*/
/*
排序算法的缺点就是:若其中有一部分数字不含有 0 ,此时排序将计算错误❌
[9,34,8] -----> [34,9,8]
错解:3498 ❌
正确:9834 ✔
sort(nums.begin(),nums.end(),greater<int>());
if(nums[i]%10==0) //当前结点含 0,就将其放在后面,要是有多个0呢?
s+=to_string(nums[i]);
else
s=to_string(nums[i])+s;
*/
// return s;
2. 正解
由于想法接连被否定,所以耗时两个小时看了答案,看完答案的第一反应是蒙的,我不知道它在讲什么,那么多数学理论我反正是不明白,于是我就在寻找其他解法,观看别人写的代码,最后我才理解答案说的是什么意思啦。
答案思路:要想知道两个数如何连起来能够得到一个最大的数,那我们就需要比较这两个数的不同顺序分别组成的结果大小是怎么样的?比如 a 与 b两个整数,先将其依次转为字符串(to_string(int val)函数实现整数转字符串)我们需要判断 a+b 与 b+a的大小关系,所以我们可以通过比较结果来判断 a、b 的先后顺序。那又如何判断 整个数组元素的之间关系呢? 那此时我们就可以利用 sort 函数的自定义规则排序,依次比较 a+b 与 b+a的大小关系,按照从大到小进行排序,此时最后获得数组就是 一个按照组成顺序最大的数字开始排列。
感觉就是我的两个思路一起使用的,唯一不同的就是 排序规则不同。
3. CODE ✔
//排序 需要自定义排序规则。
/*
一般我们选择最大数的话就是,将大数放在前面但是有一个问题需要考虑到
9,34 谁放在前面最大呢,通过简单排序的的话最后结果是349❌,而正确✔最大结果应该就是934,所以我们应该通过 两个数相加最后得到的结果进行比较,所以在此需要 自定义比较规则
*/
int n=nums.size();
sort(nums.begin(),nums.end(),cmp);
string s="";
if(nums[0]==0) return "0";//判断最高位是否是 0 ,若是0则直接返回字符串0 即可,在这里注意返回的是字符串,字符串需要用两个引号""。
for(int i=0;i<n;i++){
s+=to_string(nums[i]);
}
return s;
4. 学习点
4.1 sort 函数 自定义规则排序
4.2 int 类型 转 字符串
4.3 c++ 利用printf 输出 string
对学习点感兴趣的话可以去看我的专栏---c++基础~~~