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.
分析:
给一组非负整数,将其重新排列形成一个最大数
思路:最开始想的很简单,将nums排序[降序],与一般排序不同,它按照首位大小排序,而不是末尾排序
但,想的太过于简单,像对于12和121,并不是简单的12一定小于121,这种是前缀的情况,要单独考虑;将其拆成两部分再做比较
后来看到的具体这种比较算法,自己写,但总有点问题,又找到一种很巧妙的方法:s1和s2比较大小,比较结果,按照s1+s2和s2+s1来看,这种就不需要考虑那么多了!!
#include "stdafx.h" #include <string> #include <vector> #include <iostream> #include <algorithm> using namespace std; class Solution { public: //自定义的比较函数,为使sort调用,必须是全局或者是静态的,不能是普通成员函数 static bool compare(string &s1, string s2) {//这个比较算法设计很巧妙呢!!haoel的想法 return s1+s2 > s2+s1; } string largestNumber(vector<int> &nums) {//给一组非负整数,将其重新排列形成一个最大数 //思路:将nums排序[降序],与一般排序不同,它按照首位大小排序,而不是末尾排序 int count = nums.size(); string res(""); if(count == 0) return res; //数字转换为string vector<string> v; for(auto const &i : nums) v.push_back(to_string(i)); //按定义的比较操作降序排列字符串vector sort(v.begin(),v.end(),compare); //拼接数组数字即可 for(auto const &i : v) res += i; //针对特例int data3[] = {0,0}; if(res[0] != '0') return res; else return "0"; } }; int main() { Solution sol; int data1[] = {3,30,34,5,9}; vector<int> test1(data1,data1+sizeof(data1)/sizeof(int)); cout << sol.largestNumber(test1)<<endl; //错误示例!! int data2[] = {121,12}; vector<int> test2(data2,data2+sizeof(data2)/sizeof(int)); cout << sol.largestNumber(test2)<<endl; //错误示例!! int data3[] = {0,0}; vector<int> test3(data3,data3+sizeof(data3)/sizeof(int)); cout << sol.largestNumber(test3)<<endl; }
自己的做法,做法有问题,但又不知道问题在哪里
1 #include "stdafx.h"
2 #include <string>
3 #include <vector>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7
8 class Solution
9 {
10 public:
11 //自定义的比较函数,为使sort调用,必须是全局或者是静态的,不能是普通成员函数
12 static bool compare(int n1, int n2)
13 {
14 string s1 = to_string(n1);
15 string s2 = to_string(n2);
16 //借助string的比较函数进行比较
17 //想的太过于简单,对于12和121,并不是简单的12一定小于121,这种是前缀的情况,要单独考虑
18 //三种情况:相同,返回false;12和2,前面已比较出大小;对于一个数是另一个数的前缀,比较的就是前缀和后面的大小
19 //另外解法:直接从头到尾进行比较
20 int size1 = s1.size();
21 int size2 = s2.size();
22
23 if(size1 == size2)//不会出现前缀问题,直接比较
24 return (s1.compare(s2))>0;
25 if(size1 < size2)
26 {//判断s1是否为s2前缀
27 if(s1.compare(s2.substr(0,size1)) == 0)//是前缀,之前判断错误,要加上0
28 //比较拆分的两部分,此时需要递归调用本函数,而不能单纯调用string::compare
29 return compare(atoi(s1.c_str()), atoi(s2.substr(size1).c_str()));//注意顺序保存一致!!!
30 }
31 else
32 {//判断s2是否为s1前缀
33 if(s2.compare(s1.substr(0,size2)) == 0)//是前缀
34 //比较拆分的两部分
35 return compare(atoi(s1.substr(size2).c_str()), atoi(s2.c_str()));
36 }
37 //不是前缀,直接比较
38 return (s1.compare(s2))>0;
39 }
40 string largestNumber(vector<int> &nums)
41 {//给一组非负整数,将其重新排列形成一个最大数
42 //思路:将nums排序[降序],与一般排序不同,它按照首位大小排序,而不是末尾排序
43 int count = nums.size();
44 string res("");
45 if(count == 0)
46 return res;
47 //按定义的比较操作降序排列数组
48 sort(nums.begin(),nums.end(),compare);
49 //拼接数组数字即可
50 for(auto const &i : nums)
51 res += to_string(i);
52 //针对特例int data3[] = {0,0};
53 if(res[0] != '0')
54 return res;
55 else
56 return "0";
57 }
58 };
59
60 int main()
61 {
62 Solution sol;
63 int data1[] = {3,30,34,5,9};
64 vector<int> test1(data1,data1+sizeof(data1)/sizeof(int));
65 cout << sol.largestNumber(test1)<<endl;
66
67 //错误示例!!
68 int data2[] = {121,12};
69 vector<int> test2(data2,data2+sizeof(data2)/sizeof(int));
70 cout << sol.largestNumber(test2)<<endl;
71
72 //错误示例!!
73 int data3[] = {0,0};
74 vector<int> test3(data3,data3+sizeof(data3)/sizeof(int));
75 cout << sol.largestNumber(test3)<<endl;
76 }
参考:
http://www.cnblogs.com/ganganloveu/p/4228832.html
https://github.com/haoel/leetcode/blob/master/algorithms/largestNumber/largestNumber.cpp