zoukankan      html  css  js  c++  java
  • 把数组排成最小的数

    题目

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

    思路

     

    需要找到字典序最小的哪个排列我求出所有的排列,然后排序后取最小。进一步转化问题为全排列问题,请参考https://www.cnblogs.com/tianzeng/p/10055489.html,只不过参与排列的元素为字符串了,而不在是单纯的单个字符。 以下内容为最优的求全排列的解法,包含如何对于重复元素的处理防止不必要的处理操作。可以把排列问题分成固定第一个位置,剩余元素全排列问题。之后对剩余元素又进行同样的处理,固定第一个位置,剩余元素全排列。如图: 

    第一个想法可能就是遇到与第一部分元素相等,就不交换。比如abb, 第一个位置可分别于第二个,第三个位置交换,因为他们都不与a相同,得到 abb, bab, bba。 考察第二位置时,对于bab,第二位置会与第

    三个位置交换,得到bba。而bba已在与第一位置交换的过程中出现过了。所以单纯的看交换元素是否相等是不行的。 有重复的出现的原因为,已经有b在第一个位置出现过了,不能在有相同的元素交换到此位

    置上,即不能有重复的元素作为排列问题的第一部分,这肯定会导致重复的子问题产生。所以对于每一个位置遍历,我们添加一个set用于记录以在该位置出现过的元素。

      给出两个整数m,n,把它们拼接成mn,nm,比较他们的大小。m,n都是int类型,但是把他们拼接后就可能溢出,这是一个隐形的大数问题,所以要用字符串来解决问题。把他们拼接成字符串mn,nm后,他们的位数可定时相同的,所以比较他们的大小就可以了。要注意的是字符串的比较函数需要重新定义,不是比较a和b,而是比较ab与 ba。

    1. 若ab 大于 ba 则 a 大于 b,
    2. 若ab 小于 ba 则 a <小于b,
    3. 若ab 等于 ba 则 a 等于 b;

    如 6 61 因为 61 6 <6 61 所以 排序后为61 6

    要证明定义的比较规则有效,需要三个条件,自反性,对称性和传递性(<,>=是常规意义的大小关系,大于小于等于是自定义的大小关系)

    1. 自反性:显然有aa=aa,所以a等于a
    2. 对称性:如果a小于b,则ab小于ba,所以ba>ab,所以b大于a
    3. 传递性:如果a小于b,则ab小于ba
    class Solution
    {
        public:
            void min_num(const vector<int> &v);
    };
    bool cmp(const string &s1,const string &s2)
    {
        return s1+s2<=s2+s1?true:false;
    }
    void Solution::min_num(const vector<int> &v)
    {
        if(v.empty()||v.size()<0)
            return;
            
        //两个int类型的整数拼接到一起可能越界,所以要先转化为 字符串 
        vector<string> s(v.size(),"");//确定字符串数组的大小 
        stringstream ss;
        for(int i=0;i<v.size();++i)
        {
            ss<<v[i];
            s[i]=ss.str();
            ss.str("");    //清空stringstream对象中的内容,clear()只是清空了流的状态    
        }
        
        sort(s.begin(),s.end(),cmp);
        for(auto k:s)
            cout<<k;
        cout<<endl;
    }

     code2:

    class Solution {
    public:
        string PrintMinNumber(vector<int> num)
        {
             if(num.size()==0)
                 return "";
            
            sort(num.begin(),num.end(),cmp);
            string res;
            for(int i=0;i<num.size();++i)
                res+=to_string(num[i]);
            return res;
        }
    private://写在类内时,要加上static,lexicographical_compare 最后要求的是一个普通函数指针
                //而不是成员函数指针,所以要加static:
        static bool cmp(int a,int b)
        {
            string A(to_string(a));
            A+=to_string(b);
            string B(to_string(b));
            B+=to_string(a);
            
            return A<B;
        }
    };
  • 相关阅读:
    vue 循环Redio
    vue 子组件修改父组件变量问题
    docker安装redis
    vue 复制内容到粘贴板
    vue 组件传值
    vscode 打开多个标签页
    asp.net 文件分片上传
    css之图片下方定位遮掩层
    Python发送邮件脚本
    git添加秘钥提示Key is already in use
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10252461.html
Copyright © 2011-2022 走看看