Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9]
, the largest formed number is 9534330
.
Note: The result may be very large, so you need to return a string instead of an integer.
Credits:
Special thanks to @ts for adding this problem and creating all test cases.
题目分析:首先想到的是把数按照一定的规则排序,大的数放在前庙,小的数放在后面,然后返回结果。
其核心在于怎么比较两个数的大小:
1.首先想到的是应该从首位依次比较,值大得数放前面
2. 当两个数长度不一致,突然有个数结束了,此时怎么比较大小?我们思考,对于AB和BA谁大的问题,假设B的长度大于A,且B的前半部分跟A一样,那么BA,AB谁大的关键在于B的后半部分跟A的比较,所以我们想到当位数不够的时候用原来的数进行填充,继续比较大小结果就出来了。
对于此类问题,最好的办法就是举例子,在纸上多画画,然后就可以看出一定的规律,找到解决方案。
具体代码如下:
public String largestNumber(int[] nums) {
StringBuffer sb=new StringBuffer();
if(nums.length<0) return sb.toString();
//对于只有一个数的特殊处理
if(nums.length==1)
{
String s=castToString(nums[0]);
sb.append(s);
return sb.toString();
}
//对于全0的特殊处理
boolean flag=true;
for(int i=0;i<nums.length;i++)
{
if(nums[i]!=0)
{
flag=false;
break;
}
}
if(flag==true)
{
sb.append('0');
return sb.toString();
}
//为了省事,直接写了冒泡排序,可以尝试希尔排序和快排,速度会比较快一点
for(int i=0;i<nums.length-1;i++)
{
for(int j=i+1;j<nums.length;j++)
{
if(!compare(nums[i],nums[j]))
{
int tmp=nums[i];
nums[i]=nums[j];
nums[j]=tmp;
}
}
}
for(int i=0;i<nums.length;i++)
{
String s=castToString(nums[i]);
sb.append(s);
}
return sb.toString();
}
/*核心算法,我的想法是比较两个数的第一位数,当第一位数相等的时候,比较下一位,不够时,加上之前的那一位,当两个数相等且位数相等返回
* @return a>=b?true:false;
*/
public boolean compare(int a,int b)
{
String as=castToString(a);
//使用stringBuffer巧妙添加字符串
StringBuffer asb=new StringBuffer(as);
String bs=castToString(b);
StringBuffer bsb=new StringBuffer(bs);
int alen=as.length();
int blen=bs.length();
for(int i=0;i<alen&&i<blen;i++)
{
char ai=asb.charAt(i);
char bi=bsb.charAt(i);
//两个数不等的时候,结果很好处理
if(ai>bi) return true;
else if(ai<bi) return false;
else
{
//其中一个数不够的时候,循环叠加当前数
if(i==alen-1&&i!=blen-1)
{
asb.append(as);
alen+=as.length();
}
else if(i!=alen-1&&i==blen-1)
{
bsb.append(bs);
blen+=bs.length();
}
//两数相等且都结束,返回
else if(i==alen-1&&i==blen-1)
{
return true;
}
}
}
return true;
}
//返回的是实际位数减1,方便后面的计算。
public int getLen(int a)
{
//对于0的特殊处理
if(a==0) return 0;
int len=0;
while(a>0)
{
len++;
a=a/10;
}
return len-1;
}
public String castToString(int a)
{
StringBuffer sb=new StringBuffer();
int len=getLen(a);
while(len>=0)
{
int index=a/((int)Math.pow(10, len));
char c=(char) ('0'+index);
sb.append(c);
a=a%((int)Math.pow(10, len));
len--;
}
return sb.toString();
}
@Test
public void case1()
{
int[] nums= {3, 30, 34, 5, 9};
String s=largestNumber(nums);
String expect="9534330";
Assert.assertEquals(expect, s);
System.out.println(s);
}
@Test
public void case2()
{
int[] nums= {1};
String s=largestNumber(nums);
String expect="1";
Assert.assertEquals(expect, s);
System.out.println(s);
}
@Test
public void case3()
{
int[] nums= {121,12};
String s=largestNumber(nums);
String expect="12121";
Assert.assertEquals(expect, s);
System.out.println(s);
}
@Test
public void case4()
{
int[] nums= {34,3};
String s=largestNumber(nums);
String expect="343";
Assert.assertEquals(expect, s);
System.out.println(s);
}
@Test
public void case5()
{
int[] nums= {32,323};
String s=largestNumber(nums);
String expect="32332";
Assert.assertEquals(expect, s);
System.out.println(s);
}
@Test
public void case6()
{
int[] nums= {0,1};
String s=largestNumber(nums);
String expect="10";
Assert.assertEquals(expect, s);
System.out.println(s);
}
@Test
public void case7()
{
int[] nums= {0,0};
String s=largestNumber(nums);
String expect="0";
Assert.assertEquals(expect, s);
System.out.println(s);
}
@Test
public void case8()
{
int[] nums= {7543,7};
String s=largestNumber(nums);
String expect="77543";
Assert.assertEquals(expect, s);
System.out.println(s);
}