剑指offer(31-35)编程题

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

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n) {
        string str = std::to_string(n);
        int len = str.length();
        int first = str[0] - '0';
        if (len == 1 && first == 0) return 0;
        if (len == 1 && first > 0) return 1;;

        //最高为1
        int num1 = 0;
        if (first > 1) {
            num1 = pow(10, len - 1);
        } else if(first == 1){
            num1 = stoi(str.substr(1)) + 1;
        }
        int num2 = first * (len - 1) * pow(10, len - 2);
        return num1 + num2 + NumberOf1Between1AndN_Solution(stoi(str.substr(1)));
    }
};

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

class Solution {
public:
    static bool comp(const string& a, const string& b) {
        string ab = a + b;
        string ba = b + a;
        if(ab > ba) return false;
        return true;
    }
public:
    string PrintMinNumber(vector<int>& numbers) {
        vector<string> numStrs;
        for(size_t i=0;i<numbers.size();i++){
            numStrs.push_back(to_string(numbers[i]));
        }
        sort(numStrs.begin(),numStrs.end(),comp);

        string res;
        for(int i=0;i<numStrs.size();i++){
            res += numStrs[i];
        }
        return res;
    }
};

 33把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

 1 class Solution {
 2 public:
 3     int GetUglyNumber_Solution(int index) {
 4         vector<int> uglyArray = { 1, 2, 3, 4, 5 };
 5         if (index <= 5)
 6             return uglyArray[index - 1];
 7 
 8         int m2, m3, m5;
 9         int n1 = 1,n3 = 1,n5 = 1;
10         int k = 6;
11         while (k <= index) {
12             for (int i = n1; i < uglyArray.size(); i++) {
13                 if (2 * uglyArray[i] > uglyArray.back()) {
14                     m2 = 2 * uglyArray[i];
15                     n1 = i;
16                     break;
17                 }
18             }
19             for (int i = n3; i < uglyArray.size(); i++) {
20                 if (3 * uglyArray[i] > uglyArray.back()) {
21                     m3 = 3 * uglyArray[i];
22                     n3 = i;
23                     break;
24                 }
25             }
26             for (int i = n5; i < uglyArray.size(); i++) {
27                 if (5 * uglyArray[i] > uglyArray.back()) {
28                     m5 = 5 * uglyArray[i];
29                     n3 = i;
30                     break;
31                 }
32             }
33             uglyArray.push_back(min(min(m2,m3),m5));
34             k++;
35         }
36         return uglyArray.back();
37     }
38 };

 34.在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置。如果字符串为空,返回-1

 1 class Solution {
 2 public:
 3     int FirstNotRepeatingChar(string str) {
 4         int tableSize = 256;
 5         int *hashTable = new int[tableSize];
 6         for (int i = 0; i < 256; i++) {
 7             hashTable[i] = 0;
 8         }
 9         for (size_t i = 0; i < str.size(); i++) {
10             hashTable[static_cast<unsigned int>(str[i])]++;
11         }
12 
13         for (size_t i = 0; i < str.size(); i++) {
14             if (hashTable[static_cast<unsigned int>(str[i])] == 1)
15                 return i;
16         }
17 
18         delete[] hashTable;
19         return -1;
20     }
21 };

 35.在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 

 1 class Solution {
 2 private:
 3     int InversePairs(vector<int>&data, int left, int right) {
 4         if (left == right) return 0;
 5         int mid = left + (right - left) / 2;
 6         int leftCount = InversePairs(data, left, mid);
 7         int rightCount = InversePairs(data, mid + 1, right);
 8         int mergeCount = merge(data, left, mid, right);
 9         return (leftCount + rightCount + mergeCount)%1000000007;
10     }
11 
12     int merge(vector<int>& data, int left, int mid, int right) {
13         int* temp = new int[right - left + 1];
14         int p = mid;
15         int q = right;
16         int count = 0;
17         int k = right - left;
18         while (p >= left && q > mid) {
19             if (data[p] > data[q]) {
20                 count = (count + q - mid)%1000000007;
21                 temp[k--] = data[p--];
22             } else {
23                 temp[k--] = data[q--];
24             }
25         }
26         while (p >= left) {
27             temp[k--] = data[p--];
28         }
29         while (q > mid) {
30             temp[k--] = data[q--];
31         }
32         for (int i = 0; i <= right - left; i++) {
33             data[left + i] = temp[i];
34         }
35         delete[] temp;
36         return count;
37     }
38 public:
39     int InversePairs(vector<int> data) {
40         int n = data.size();
41         if (n < 2)
42             return -1;
43         return InversePairs(data, 0, n - 1);
44     }
45 };

 

转载于:https://www.cnblogs.com/wxquare/p/6649084.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值