(剑指offer)1到n中数字1出现的次数 把数组排成最小的数

1到n中数字1出现的次数

        首先看一个例子,21345。

        个位数从0到9周期变化,每个周期都会出现一次1,总共有2134个周期,因此有2134个1,而且其个位数字为5,因此在第2134周期时还会经过0-5,又会出现一次1,加起来就有2135个1。

        再看十位数字,同样,0-9也会周期变化,总共会经过213个周期,但是此时因为个位数字的存在,十位数字的1会经过十个数才能够变成2,因此每个周期1出现的次数就是10,同样,此时其十位数字为4,又会经过0-4的变化,所以总共会出现213×10+10=2120个1。

        百位数字同上,21×100+100=2200个1。

        千位数字不一样,因为此时千为数字是1,其最后一个周期1不是完整,只会变化到345,再加上其本身的1,会有2×100+345+1=2340个1。

        万位数字此时一个0-9的变化的完成不了,只能完成0-2,故总共有10000个1。

       

int NumberOf1Between1AndN_Solution(int n)
    {
        int res=0,weight=0,base=1,prev=0;
        while(n>0) {
            weight=n%10;
            n/=10;
            res+=n*base;
            if(weight==1) 
                res+=(prev+1);
            else if(weight>1) 
                res+=base;
            prev+=weight*base;
            base*=10;
        }
        return res;
    }

把数组排成最小的数

        对于数组{3,32,321},结果应该是321323。思路就是将数组排序,而且按照每一位数字的大小来排序,对于上面数组来说,比较32和321,前两位数字相等,但是321的最后以为数字比32的第一位数字小,那么其排在32的前面,我们可以用下面这个函数来实现上述的比较:

bool cmp(int a,int b) {
    string s1=to_string(a);
    string s2=to_string(b);
    string str1=s1+s2,str2=s2+s1;
    return str1<str2;
}

然后利用上述函数对数组排序求得结果:

string PrintMinNumber(vector<int> numbers) {
        sort(numbers.begin(),numbers.end(),cmp);
        string res="";
        for(int i=0;i<numbers.size();++i) 
            res+=to_string(numbers[i]);
        return res;
    }

猜你喜欢

转载自blog.csdn.net/w1157984197/article/details/79733690