《剑指offer》面试题33、32——把数组排成最小的数、整数中1出现的次数

33.把数组排成最小的数

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

代码:

```
#include<iostream>
#include<algorithm>
using namespace std;

//链接:https://www.nowcoder.com/questionTerminal/8fecd3f8ba334add803bf2a06af1b993
//来源:牛客网

/*对vector容器内的数据进行排序,按照 将a和b转为string后
 若 a+b<b+a  a排在在前 的规则排序,
 如 2 21 因为 212 < 221 所以 排序后为 21 2 
  to_string() 可以将int 转化为string
*/

class Solution
{
    public:
        static bool cmp(int a,int b)
        {
            string A="";
            string B="";
            A+=to_string(a);
            A+=to_string(b);
            B+=to_string(b);
            B+=to_string(a);

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




int main()
{

//    int Min=NumberOf1Between1AndN_Solution(12);
//    cout<<Min<<endl;
    vector<int> vec={3,32,321};


    Solution t;

    string ans=t.PrintMinNumber(vec);
    cout<<ans<<endl;
       return 0;
}

32.面试题32:整数中1出现的次数(从1到n整数中1出现的次

求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。

解法1:
链接:https://blog.csdn.net/yi_afly/article/details/52012593
https://blog.csdn.net/crazy__chen/article/details/48597577

对于某个位置,它可以是大于1,等于1,等于0:

若cur为0,则1出现次数为round*base
若cur为1,则1出现次数为round*base+former+1
若cur大于1,则1出现次数为rount*base+base

比如:

534 = (个位1出现次数)+(十位1出现次数)+(百位1出现次数)=(53*1+1)+(5*10+10)+(0*100+100)= 214
530 = (53*1)+(5*10+10)+(0*100+100) = 213
504 = (50*1+1)+(5*10)+(0*100+100) = 201
514 = (51*1+1)+(5*10+4+1)+(0*100+100) = 207
10 = (1*1)+(0*10+0+1) = 2

代码:


public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int i = 1;
        int before=0;//由i位前决定的1数目(高位)
        int current = 0;//由i位决定的1数目
        int after=0;//由i位后决定的1数目(低位)
        int count = 0;
        while((n/i)>0){
            current = (n/i)%10;
            before = n/i/10;
            after = n - (n / i) * i;
            if(current>1){
                count = count + (before + 1) * i;
            }else if (current == 0){
                count = count + before * i;
            }else if (current == 1){
                count = count + before * i + after + 1;
            }
            i = i * 10;
        }
        return count;
    }
}

解法二:常规解法:

代码:

int NumberOf1Between1AndN_Solution(int n)
{
        int count = 0;
        for(int i=0; i<=n; i++)
        {
                int temp = i;
                //如果temp的任意位为1则count++
                while(temp)
                    {
                        if(temp%10 == 1){
                            count++;
                        }
                temp /= 10;
        }
    }
    return count;
}

猜你喜欢

转载自blog.csdn.net/zhenaoxi1077/article/details/80487354