剑指offer45~55题

数字序列中某一位的数字
在这里插入图片描述

class Solution {
   
public:
    int digitAtIndex(int n) {
   
         long long i = 1, s = 9, base = 1;//i表示是几位数,s表示位数共有多少个,base表示位数的起始值。
         while(n > i * s) {
      // 9, 90, 900, 9000, 90000, i * s表示位数总共占多少位。
             n -= i * s;         // 1000 - 9 - 90 * 2 - 900 * 3 ,当i= 3 时不符合条件,说明是在三位数里面。
             i ++;                
             s *= 10;
             base *= 10;
         }
         //求第i位数的第几个数, 1000 - 9 - 180 = n , n / 3 + base - 1(考虑0故减1), 
         //c++中只有下取整,所以当需要上取整时要处理一下,也就是说 n/i向上取整等价于 (n + i - 1)/i。
         int number = base + (n + i - 1) / i - 1; 
         int r = n % i ? n % i : i;              // 除不尽就是第几位,除尽力了就是最后一位。
         for (int j = 0; j < i - r; j ++) number /= 10; //求数的第i - r位,取出第i - r位。

         return number % 10;
    }
};

把数组排成最小的数
也是一道非常经典的题目。

  1. 首先我们需要知道什么样的数应该放在前面,所以我们需要定义两个数的排序。这个排序规则并不只是单纯的比较数值的大小,例如:321,32尽管32小于321的但是32132是小于32321的,所以我们需要自己定义一种排序规则,用来替换原来的符号比较。比较的思路为:如果ab<ba那么就说a比b“小”,a应该放在b的前面。
  2. 然后有了比较规则之后我们就可以进行判断,将数组中“小”的元素放在数组的前面,最后将数组每个元素按照顺序拼接输出就可以了。
class Solution {
   
public:

    static bool mycmp(int a, int b) {
   
        auto as = to_string(a), bs = to_string(b);
        return as + bs < bs + as;
    }
    
    string printMinNumber(vector<int>& nums) {
   
        string res;
        sort(nums.begin(), nums.end(), mycmp);
        for (auto x : nums) res += to_string(x);
        return res;
    }
};

把数字翻译成字符串
绝大部分的计数问题都可以看成是dp问题。
类比爬楼梯,dp[n] = dp[n-1]+dp[n-2],dp[n]代表走到最后一个字符,能有多少多少中翻译方法。对于访问到当前的字符dp[n],能有多少中翻译?

  1. 当前字符翻译为1个字符这是一种方法,dp[n] = dp[n-1]
  2. 当前字符呵前一个字符共同翻译为一种方法 dp[n]+=dp[n-2],此时的条件为前后两个字符可以翻译为同一个字符。还有 04,05,06,这种只能翻译为1中,其组合不能作为一种翻译,所以要在[10,25]
class Solution {
   
public:
    int getTranslationCount(string s) {
   
        int n = s.size();
        vector<int> f(n + 1);
        f[0] = 1;
        for (int i = 1; i <= n; i++) {
   
            f[i] += f[i- 1];
            int t = (i >= 2) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值