当前位置: 首页 > news >正文

LeetCode.2999. 统计强大整数的数目

统计强大整数的数目

  • 题目
  • 整体思路
  • Code
  • 代码详细解释
    • `calculate` 函数
    • `numberOfPowerfulInt` 函数
  • 复杂度分析

题目

2999. 统计强大整数的数目

给你三个整数 startfinishlimit 。同时给你一个下标从 0 开始的字符串 s ,表示一个 整数。

如果一个 整数 x 末尾部分是 s (换句话说,sx后缀),且 x 中的每个数位至多是 limit ,那么我们称 x强大的

请你返回区间 [start..finish] 内强大整数的 总数目

如果一个字符串 xy 中某个下标开始(包括 0 ),到下标为 y.length - 1 结束的子字符串,那么我们称 xy 的一个后缀。比方说,255125 的一个后缀,但不是 512 的后缀。

示例 1:
输入:start = 1, finish = 6000, limit = 4, s = "124"
输出:5
解释:区间 [1..6000] 内的强大数字为 124 ,1124 ,2124 ,3124 和 4124 。这些整数的各个数位都 <= 4 且 "124" 是它们的后缀。注意 5124 不是强大整数,因为第一个数位 5 大于 4 。
这个区间内总共只有这 5 个强大整数。

示例 2:
输入:start = 15, finish = 215, limit = 6, s = "10"
输出:2
解释:区间 [15..215] 内的强大整数为 110 和 210 。这些整数的各个数位都 <= 6 且 "10" 是它们的后缀。
这个区间总共只有这 2 个强大整数。

示例 3:
输入:start = 1000, finish = 2000, limit = 4, s = "3000"
输出:0
解释:区间 [1000..2000] 内的整数都小于 3000 ,所以 "3000" 不可能是这个区间内任何整数的后缀。

整体思路

代码通过两个主要函数 calculatenumberOfPowerfulInt 来完成计算。

  • calculate 函数:用于计算小于等于给定整数 x 且以字符串 s 为后缀,同时每个数位都不超过 limit 的整数的数量。
  • numberOfPowerfulInt 函数:利用 calculate 函数,通过计算 finishstart - 1 对应的满足条件的整数数量,然后相减得到区间 [start, finish] 内满足条件的整数数量。

Code

long long calculate(const char* x, const char* s, int limit) {
    int x_len = strlen(x);
    int s_len = strlen(s);
    if (x_len < s_len) {
        return 0;
    }
    if (x_len == s_len) {
        return strcmp(x, s) >= 0 ? 1 : 0;
    }

    char* suffix = (char*)malloc(s_len + 1);
    strncpy(suffix, x + x_len - s_len, s_len);
    suffix[s_len] = '\0';
    long long count = 0;
    int preLen = x_len - s_len;
    
    for (int i = 0; i < preLen; i++) {
        int digit = x[i] - '0';
        if (limit < digit) {
            count += (long long)pow(limit + 1, preLen - i);
            free(suffix);
            return count;
        }
        count += (long long)digit * (long long)pow(limit + 1, preLen - 1 - i);
    }
    if (strcmp(suffix, s) >= 0) {
        count++;
    }
    free(suffix);
    return count;
}

long long numberOfPowerfulInt(long long start, long long finish, int limit, const char* s) {
    char start_[20], finish_[20];
    sprintf(start_, "%lld", start - 1);
    sprintf(finish_, "%lld", finish);
    return calculate(finish_, s, limit) - calculate(start_, s, limit);
}

代码详细解释

calculate 函数

long long calculate(const char* x, const char* s, int limit) {
    int x_len = strlen(x);
    int s_len = strlen(s);
    if (x_len < s_len) {
        return 0;
    }
    if (x_len == s_len) {
        return strcmp(x, s) >= 0 ? 1 : 0;
    }

    char* suffix = (char*)malloc(s_len + 1);
    strncpy(suffix, x + x_len - s_len, s_len);
    suffix[s_len] = '\0';
    long long count = 0;
    int preLen = x_len - s_len;
    
    for (int i = 0; i < preLen; i++) {
        int digit = x[i] - '0';
        if (limit < digit) {
            count += (long long)pow(limit + 1, preLen - i);
            free(suffix);
            return count;
        }
        count += (long long)digit * (long long)pow(limit + 1, preLen - 1 - i);
    }
    if (strcmp(suffix, s) >= 0) {
        count++;
    }
    free(suffix);
    return count;
}
  • 参数说明

    • x:表示一个整数的字符串形式。
    • s:表示后缀字符串。
    • limit:表示每个数位的上限。
  • 逻辑步骤

    1. 长度检查
    • x 的长度小于 s 的长度,说明 x 不可能以 s 为后缀,直接返回 0。
    • x 的长度等于 s 的长度,使用 strcmp 函数比较 xs,若 x 大于等于 s,则返回 1,否则返回 0。
    1. 提取后缀
    • 分配内存给 suffix 用于存储 x 的后缀部分,长度为 s_len
    • 使用 strncpy 函数复制 x 的后缀部分到 suffix,并添加字符串结束符 '\0'
    1. 计算前缀部分的组合数
    • preLen 表示 x 除去后缀部分的长度。
    • 遍历 x 的前缀部分,对于每个数位:
      • 若该数位大于 limit,则计算剩余部分所有可能的组合数(每个数位可以取 0 到 limitlimit + 1 种值),并返回结果。
      • 否则,累加当前数位乘以剩余部分所有可能的组合数。
    1. 检查后缀
    • suffix 大于等于 s,则满足条件的整数数量加 1。
    1. 释放内存并返回结果
    • 释放 suffix 分配的内存,并返回满足条件的整数数量。

numberOfPowerfulInt 函数

long long numberOfPowerfulInt(long long start, long long finish, int limit, const char* s) {
    char start_[20], finish_[20];
    sprintf(start_, "%lld", start - 1);
    sprintf(finish_, "%lld", finish);
    return calculate(finish_, s, limit) - calculate(start_, s, limit);
}
  • 参数说明

    • start:区间的起始值。
    • finish:区间的结束值。
    • limit:每个数位的上限。
    • s:表示后缀字符串。
  • 逻辑步骤

    1. 将整数转换为字符串
    • 使用 sprintf 函数将 start - 1finish 转换为字符串形式,分别存储在 start_finish_ 中。
    1. 计算区间内满足条件的整数数量
    • 调用 calculate 函数分别计算小于等于 finish 和小于等于 start - 1 的满足条件的整数数量。
    • 两者相减得到区间 [start, finish] 内满足条件的整数数量,并返回结果。

复杂度分析

  • 时间复杂度calculate 函数的时间复杂度为 O ( l o g 10 x ) O(log_{10}x) O(log10x),其中 x x x 是输入的整数。numberOfPowerfulInt 函数调用两次 calculate 函数,因此总的时间复杂度也是 O ( l o g 10 f i n i s h ) O(log_{10}finish) O(log10finish)
  • 空间复杂度:主要是 calculate 函数中分配的 suffix 数组的空间,空间复杂度为 O ( l o g 10 x ) O(log_{10}x) O(log10x),其中 x x x 是输入的整数。

相关文章:

  • SAP系统控制检验批
  • 多模态人工智能:从感知到认知的跨越
  • 操作系统 3.1-内存使用和分段
  • BeeWorks:高效协作的局域网聊天工具
  • 《Vue Router实战教程》21.扩展 RouterLink
  • 设计模式 四、行为设计模式(2)
  • 苍穹外卖2
  • 算法训练之动态规划(四)——简单多状态问题
  • AutoEval:现实世界中通才机器人操作策略的自主评估
  • 电机控制储备知识 四:电机的分类
  • 示波器测量纹波噪声的一些建议
  • JavaScript 实现 WiFi 信号强度模拟类
  • C++顺序栈的实现
  • 蓝桥杯比赛 python程序设计——神奇闹钟
  • 图像颜色空间对比(Opencv)
  • 【Nginx】Nginx代理Tomcat配置及404问题解决
  • JavaScript逆向工程:如何判断对称加密与非对称加密
  • LLM应用开发(七)--记忆
  • 聊一聊接口测试时遇到第三方服务时怎么办
  • map映射到二维数组
  • 专业创建网站公司/电脑系统优化软件哪个好用
  • 如何做婚介网站/关键词优化公司哪家推广
  • 南京专业网站设计哪个品牌/关键词seo排名公司
  • 网站建设属于什么经济科目/网络推广理实一体化软件
  • 做音乐网站需要版权么/企业网上的推广
  • 深圳做网站哪家好/河南做网站优化