leetcode:Largest Number

本文探讨如何通过特定的排序算法将一组非负整数排列组合,形成最大的数值序列。详细介绍了比较规则、特殊处理及算法实现过程,并通过实例验证了算法的有效性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
   }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值