<LeetCode OJ> 179. Largest Number

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.



分析:

思路首先:为了能凑成最大数,开头大的数成为新数的起始位,同时题目说了是排序问题
那么显然我们应该按照"字典"顺序来排数但是我们又不能简单的按照字典顺序,
举例:[3, 30, 34, 5, 9]已经是字典顺序了,但是“最大数”顺序应该为[30, 3, 34, 5, 9],所以9534330
所以规则应该如下:
给定两个非负整数:a, b
将它们转换成字符串形式,然后进行连接。可得两种结果:
a在前,b在后,记为:strAB
b在前,a在后,记为:strBA
如果strAB > strBA,那么排序时a在b的前面。

class Solution {
public:
    //不能简单的按字典序排序即小的在前面。  
    //比如32的字典序比322小,但是32322比32232大,  
    static  bool cmp(const string &str1, const string &str2)   //为什么这里要加一个static 关键字才行???????
    {  
        string _str1 = str1;  
        string _str2 = str2;  
        _str1.append(str2);//在_str1后面追加str2字符串  
        _str2.append(str1);  
        return _str2 < _str1;//true则将对原字符串顺序颠倒,否则不处理  
    }
    string largestNumber(vector<int>& nums) {
        int len=nums.size();
        string strnum[1000];
        string result;
        if(len==0)
            return result;
        for (int i = 0; i < len; i++)   
            strnum[i] = to_string(nums[i]);   //将数字转换到strnum数组中  
        sort(strnum,strnum+len,cmp);    
        for (int i = 0; i < len; i++)   
            result.append(strnum[i]);   //将字符数字转换到结果字符串中
        auto pos = result.find_first_not_of('0');
        return pos == string::npos ? "0" : result.substr(pos);    
    }
};

学习别人的代码,精炼.....:

class Solution
{
public:
    string largestNumber(vector<int>& nums)
    {
        sort(nums.begin(), nums.end(), compare);//直接对数组进行自定义的字典顺序“排序”
        string res;
        for (auto n : nums)
            res += to_string(n);
        auto pos = res.find_first_not_of('0');//找到第一个不为‘0’的位置
        return pos == string::npos ? "0" : res.substr(pos);//如果位置pos不存在(即全是‘0’)则返回‘0’,否则返回pos开始的子字符串
    }

private:
    static bool compare(int a, int b)
    {
        auto strA = to_string(a);
        auto strB = to_string(b);
        return (strA + strB > strB + strA);
    }
};



本题参考以前在九度写的代码:

题目1504:把数组排成最小的数


题目描述:

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

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数。
输入的第二行包括m个正整数,其中每个正整数不超过10000000。

输出:

对应每个测试案例,
输出m个数字能排成的最小数字。

样例输入:
3
23 13 6
2
23456 56
样例输出:
13236
2345656
#include "vector"    
#include <iostream>    
#include "algorithm"    
#include<string>  
#include <stdio.h>  
#include<cmath>  
#include<cstdlib>  
   
using namespace std;  
   
 long long numbers[200];  
string str_num[200];  
   
//不能简单的按字典序排序即小的在前面。  
//比如32的字典序比322小,但是32322比32232大,  
bool cmp(const string &str1, const string &str2)   
{  
    string _str1 = str1;  
    string _str2 = str2;  
    _str1.append(str2);//在_str1后面追加str2字符串  
    _str2.append(str1);  
    return _str1 < _str2;//true则将对原字符串顺序颠倒,否则不处理  
}  
   
int main() {  
    int n;  
    while (scanf("%d", &n) != EOF)   
    {  
        //接受输入  
        for (int i = 0; i < n; i++)  
            scanf("%d", numbers + i);  
   
        for (int i = 0; i < n; i++)   
        {  
            char str[20];  
            sprintf(str, "%d", numbers[i]);//将数字转换到str内存中  
            str_num[i] = str;  
        }  
   
        sort(str_num, str_num + n, cmp);  
   
        for (int i = 0; i < n; i++)   
            cout << str_num[i];  
           
        cout << endl;  
    }  
    return 0;  
}  
/**************************************************************  
    Problem: 1504  
    User: EbowTang  
    Language: C++  
    Result: Accepted  
    Time:220 ms  
    Memory:1524 kb  
****************************************************************/  


注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/50511705

原作者博客:http://blog.csdn.net/ebowtang

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值