一:剑指45把数组组成最小的数。

1.题目描述

image.png

2.代码

自己暴力

这个代码没有参考意义,因为不会使用sort和自己写关于字符串的比较怎么比价的排序算法,算是暴力破解的。

  1. class Solution {
  2. public:
  3. string minNumber(vector<int>& nums) {
  4. vector<string> arr;
  5. for (int i = 0; i < nums.size(); i++)
  6. {
  7. arr.push_back(to_string(nums[i]));
  8. }
  9. sort(arr.begin(), arr.end());
  10. string str = "";
  11. for (int i = 1; i < nums.size(); i++)
  12. {
  13. if((arr[i - 1] + arr[i]).size() > 10) {
  14. // 防止两个数字太大,int最多10位,
  15. //超过10位截断,下面的if很可能不应该进去,反而进去了,必须提前杜绝过大的数字
  16. continue;
  17. }
  18. int a = atoi((arr[i - 1] + arr[i]).c_str());
  19. // atoi函数接收的参数必须是c字符数组的形式,所以必须c_str函数把cpp字符串变成字符数组,
  20. //传给atoi
  21. int b = atoi((arr[i] + arr[i - 1]).c_str());
  22. if (a > b) {
  23. for (int j = 0; j <= i; j++) // 3----3 --- 30,30一定得到第一个3的前面才行
  24. {
  25. if (arr[i - 1] == arr[j])
  26. {
  27. swap(arr[j], arr[i]);
  28. break;
  29. }
  30. }
  31. }
  32. }
  33. for (int i = 0; i < arr.size(); i++)
  34. {
  35. str += arr[i];
  36. }
  37. return str;
  38. }
  39. };

自己排序的版本:

  • 其实自己写关于字符串的排序比较,最难的地方就是不明白如何排序,根据什么排序。如何定义大于和如何定义小于。https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/solution/mian-shi-ti-45-ba-shu-zu-pai-cheng-zui-xiao-de-s-4/
  • 上面的网址说的很清楚怎么比较,其实sort第三个参数写的时候,也得明白上面网址的原理,不然还是不会写,所以自己才用上面比较麻烦的。
  • K神是上交大的,上面网址就是他写的

    1. class Solution {
    2. public:
    3. string minNumber(vector<int>& nums) {
    4. vector<string> arr;
    5. for (int i = 0; i < nums.size(); i++)
    6. {
    7. arr.push_back(to_string(nums[i]));
    8. }
    9. quick_sort(arr, 0, arr.size() - 1);
    10. string str = "";
    11. for (int i = 0; i < arr.size(); i++)
    12. {
    13. str += arr[i];
    14. }
    15. return str;
    16. }
    17. void quick_sort(vector<string>& arr, int l, int r)
    18. {
    19. if (l >= r) return;
    20. int i = l - 1, j = r + 1;
    21. string x = arr[i + j >> 1];
    22. while (i < j)
    23. {
    24. while (arr[++i] + x < x + arr[i]);
    25. while (arr[--j] + x > x + arr[j]);
    26. if (i < j) swap(arr[i], arr[j]);
    27. }
    28. quick_sort(arr, l, j);
    29. quick_sort(arr, j + 1, r);
    30. }
    31. };
  • 研究sort函数,sort函数第三个参数的构造,之前在结构体上见过那种特殊的排序,题目在y总第五章贪心算法那里有涉及,代码如下,本质我们就是对Range的结构体进行排序,我们就在结构体里面写这个结构体的比较运算符,相当于就是运算符的重载,重载< 的时候,参数之能有一个,sort函数第三个参数不用写内容,是局部的一种函数写法

  • 一定比较两种写法的不同,暂且叫做一个局部,一个全局的写法,局部的写法也就是代码1部分,参数只需要一个,全局的写法,代码2部分,参数也需要两个。

代码1:

  1. struct Range
  2. {
  3. int l,r;
  4. bool operator <(const Range &W)const
  5. {
  6. return l<W.l;
  7. }
  8. }range[N];
  9. sort(range,range+n); // 不是全局写法,直接类内部对运算符重载

代码2:

  1. struct Range
  2. {
  3. int l,r;
  4. bool operator() (const Range &W, const Range& s)const
  5. {
  6. return W.l < s.l;
  7. }
  8. } rg,range[N];
  9. sort(range,range+n, rg); // 如果是两个参数,可以叫做全局的写法的时候,第三个参数需要传递一个对象

系统提供的sort函数

  1. class Solution {
  2. public:
  3. bool operator() (string& a, string& b) const
  4. {
  5. return a + b < b + a;
  6. // 这里就是全局的写法,因为比较的内容并不是Solution的写法, 所以operator<不能用
  7. }
  8. string minNumber(vector<int>& nums) {
  9. vector<string> arr;
  10. for (int i = 0; i < nums.size(); i++)
  11. {
  12. arr.push_back(to_string(nums[i]));
  13. }
  14. sort(arr.begin(), arr.end(), Solution()); // Solution()就是创造一个对象
  15. string str = "";
  16. for (auto& c : arr)
  17. {
  18. str += c;
  19. }
  20. return str;
  21. }
  22. };

一对元素,先按照第一个从大到小,第二个从小到大

  1. struct op1{
  2. bool operator() (const vector<int>& s1, const vector<int>& s2) const
  3. {
  4. return (s1[0] > s2[0]) || (s1[0] == s2[0] && s1[1] < s2[1]);
  5. }
  6. };