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
时间: 2024-10-26 15:07:46