首页 > 其他分享 >2376.统计特殊整数

2376.统计特殊整数

时间:2024-09-22 21:12:08浏览次数:1  
标签:数字 int permutations 整数 选择 ans 2376 统计

如果一个正整数每一个数位都是 互不相同 的,我们称它是 特殊整数 。

给你一个 正 整数 n ,请你返回区间 [1, n] 之间特殊整数的数目。

示例 1:

输入:n = 20
输出:19
解释:1 到 20 之间所有整数除了 11 以外都是特殊整数。所以总共有 19 个特殊整数。
示例 2:

输入:n = 5
输出:5
解释:1 到 5 所有整数都是特殊整数。
示例 3:

输入:n = 135
输出:110
解释:从 1 到 135 总共有 110 个整数是特殊整数。
不特殊的部分数字为:22 ,114 和 131 。

解题思路:
思路一:
1.使用位运算
实现思路
1.初始化位图:使用一个整数 bitmap 作为位图,每一位代表一个数字是否存在。
2.遍历数字的每一位:每次取出数字的最后一位,并检查该位是否已经在位图中被设置过。
3.设置位图:如果该位未被设置,则将其设置为 1。
4.返回结果:如果整个数字遍历完成后没有重复的数字,则返回 true;否则返回 false。

  该思路提交还是超时了,那如何解决超时的问题呢?
    
   上述代码虽然使用了位图来减少内存的使用,但是时间复杂度还是未能解决?如果我们从数字的本身出发那么只需要关注每个数字位置不重复就可以了,具体的思路为:
        1.将输入整数n转换为字符串s,初始化结果变量ans、排列数变量permutations。
        2.计算小于s长度的所有位数的非重复数字组合总数。
        3.遍历s中的每个字符,计算相同位数中不大于当前数字的非重复组合数,并累加到ans。
        4.判断是否所有数字均不重复,若是,则结果ans加一。
        5.返回最终结果ans。
    步骤分解:
        1.先把整数转换成字符串
             String s = Integer.toString(n);
        2.计算所有位数小于s的非重复数字组合的总数,并累加到ans中
              int ans = 0;
              int permutations = 1;
              //遍历字符串s从第2个字符到最后一个字符
              for (int i = 1; i < s.length(); i++) {
                  ans += 9 * permutations;
                  permutations *= 10 - i;
              }
              这里解释下这段代码的含义:
                  permutations 表示的是在当前位置可以选取的不同数字的数量。对于每一位,可选的数字数量会根据位的位置变化。
                      对于第一位(十位),可以选择 1 到 9 中的任意一个数字(不能选择 0),因此有 9 种选择。
                      对于第二位(个位),可以选择剩下的 0 到 9 中的 9 个数字(排除已经选择的那一个数字),因此有 9 种选择。
                      对于第三位,可以选择剩下的 8 个数字,以此类推。
                      因此,在两位数的情况下,permutations 的初始值为 9(第一位的选择),然后乘以 9(第二位的选择),得到 81 种组合。每次循环中,permutations 会被更新为下一个位置的可选数字数量。
                      具体来说:
                      第一位:9 种选择。
                      第二位:9 种选择。
                      所以 permutations 在两位数情况下始终为 9
        3.该函数计算字符串s中不同数字组合的数量。主要步骤如下:
          int set = 0;
    for (int i = 0; i < s.length(); i++) {
          // 转换为数字
          int num = s.charAt(i) - '0';
          // 该行代码生成一个位掩码。具体功能如下:
          //   1 << num:将1左移num位,得到一个二进制数,该二进制数的最高位为1,其余为0。
          //   (1 << num) - 1:将上述结果减1,得到一个二进制数,该数的前num位全为1。例如,若num为3,则结果为0b11
          int mask = (1 << num) - 1;
          // 该表达式计算(set & mask) ^ mask的结果中的二进制位1的数量。 具体步骤如下:
          //     set & mask:对set和mask进行按位与操作。
          //     (set & mask) ^ mask:将上一步结果与mask进行按位异或操作。
          //      Integer.bitCount(...):计算第2步结果中二进制位1的数量。
          int count = Integer.bitCount((set & mask) ^ mask);
          if (i == 0) {
              count--;
          }
          // 这段代码将 count 与 permutations 的乘积累加到 ans 中。具体功能如下:
          // 将 count 与 permutations 相乘。
          //将乘积结果累加到变量 ans 中。这通常用于计算某种组合或排列的总数
          ans += count * permutations;
          if ((set & (1 << num)) != 0) {
              break;
          }
          permutations /= 10 - (i + 1);
          set |= 1 << num;
        }
        if (Integer.bitCount(set) == s.length()) {
            ans++;
        }
        return ans;
      代码整体思路:
          1.初始化变量set为0。
          2.遍历字符串s中的每个字符,将其转换为数字,并计算掩码mask。
          3.使用位运算统计当前数字在已处理子串中的出现次数count。
          4.如果是第一个字符,则count减1。
          5.更新答案ans。
          6.检查数字是否重复,若重复则提前结束循环。
          7.更新排列数permutations。
          8.将当前数字加入已处理集合set。
          9.最后检查所有数字是否唯一,若是,则ans加1。
          10.最终返回结果ans

    整体代码:
        class Solution {
          public static int countSpecialNumbers(int n) {
              String s = Integer.toString(n);
              int ans = 0;
              int permutations = 1;
              if(n <= 9){
                  return n;
              }
              // 遍历字符串s从第2个字符到最后一个字符
              for (int i = 1; i < s.length(); i++) {
                  ans += 9 * permutations;
                  permutations *= 10 - i;
              }
              int set = 0;
              for (int i = 0; i < s.length(); i++) {
                  // 转换为数字
                  int num = s.charAt(i) - '0';
                  // 该行代码生成一个位掩码。具体功能如下:
                  //   1 << num:将1左移num位,得到一个二进制数,该二进制数的最高位为1,其余为0。
                  //   (1 << num) - 1:将上述结果减1,得到一个二进制数,该数的前num位全为1。例如,若num为3,则结果为0b11
                  int mask = (1 << num) - 1;
                  // 该表达式计算(set & mask) ^ mask的结果中的二进制位1的数量。 具体步骤如下:
                  //     set & mask:对set和mask进行按位与操作。
                  //     (set & mask) ^ mask:将上一步结果与mask进行按位异或操作。
                  //      Integer.bitCount(...):计算第2步结果中二进制位1的数量。
                  int count = Integer.bitCount((set & mask) ^ mask);
                  if (i == 0) {
                      count--;
                  }
                  // 这段代码将 count 与 permutations 的乘积累加到 ans 中。具体功能如下:
                  // 将 count 与 permutations 相乘。
                  //将乘积结果累加到变量 ans 中。这通常用于计算某种组合或排列的总数
                  ans += count * permutations;
                  if ((set & (1 << num)) != 0) {
                      break;
                  }
                  permutations /= 10 - (i + 1);
                  set |= 1 << num;
              }
              if (Integer.bitCount(set) == s.length()) {
                  ans++;
              }
              return ans;
          }
      }

标签:数字,int,permutations,整数,选择,ans,2376,统计
From: https://www.cnblogs.com/java-cheng/p/18422008

相关文章

  • 数据处理与统计分析篇-day08-apply()自定义函数与分组操作
    一.自定义函数概述当Pandas自带的API不能满足需求,例如:我们需要遍历的对Series中的每一条数据/DataFrame中的一列或一行数据做相同的自定义处理,就可以使用Apply自定义函数apply函数可以接收一个自定义函数,可以将Series对象的逐个值或DataFrame的行/列数据传递给自......
  • C语言整数类型的存储空间和取值范围
    C语言整数类型的存储空间和取值范围四种整数类型char,short,int,long默认有符号,再加上无符号限制,共8种情况char//字符型,单字节,取值范围:CHAR_MIN-CHAR_MAXunsignedchar//无符号字符型,取值范围:0-UCHAR_MAXshortint//短整型,双......
  • 地统计常用公式与概念介绍:插值、平稳假设、变异函数、块金、克里格、线性无偏等
      本文对插值、平稳假设、变异函数、克里格等常用的地学计算概念加以介绍,并对相关公式进行推导。1引言  我们由地学计算的几个基本概念入手,对相关理论方面的内容加以一定了解。  需要注意的是,以下内容如果单独来看或许有些不好理解,但一旦将其与实际应用结合,便会豁然开朗......
  • 【python】石头剪刀布,模拟十次并统计获胜次数
    解决问题下面是一个使用Python编写的剪刀、石头、布游戏的程序,包含玩家与计算机对战和模拟计算机对战10次的功能。importrandomdefget_computer_choice():  returnrandom.randint(0,2)defget_user_choice():  choice=input("请输入剪刀(0)、石头(1)、布(......
  • Python中的同一运算符与整数缓存问题
    在Python中,is运算符与==运算符的使用常常引发混淆。特别是在处理小整数时,Python会进行整数缓存,以提高性能。本文将深入探讨同一运算符(is)与相等运算符(==)的区别,并详细阐述整数缓存的问题,通过具体的代码示例和运行结果来帮助理解。1.同一运算符与相等运算符is运算符:判断两个对象是否......
  • python+flask计算机毕业设计教师工作量统计系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在高等教育快速发展的今天,教师作为教育的核心力量,其工作量的准确统计与评估成为了高校管理中不可或缺的一环。传统的教师工作量统计方式往......
  • 算法解析:二分查找实现整数平方根
    题目:给你一个非负整数 x ,计算并返回 x 的算术平方根 。由于返回类型是整数,结果只保留整数部分 ,小数部分将被舍去。注意:不允许使用任何内置指数函数和算符,例如 pow(x,0.5) 或者 x**0.5 。示例1:输入:x=4输出:2示例2:输入:x=8输出:2解释:8的算术平方根是2.82842.........
  • 华为OD机试真题-IPv4地址转换成整数-2024年OD统一考试(E卷)
     最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客     每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,持续跟新。 题目描述存在一种虚拟IPv4地址,由4......
  • 【C++】数组案例:考试成绩统计
    要求:一个简单的二维数组使用案例,用于统计三个学生在三门课程中的考试成绩总分。代码要点:二维数组声明和初始化:intscore[3][3]:声明一个3行3列的二维数组,用于存储三个学生的三门课程成绩。初始化列表:为数组的每个元素赋初始值。总分统计:外层循环:遍历每个学生(行)。......
  • 偶数、奇数、整数与指数
    引言        在前面的课程中,我们已经学习了Python的基本输入输出、数据类型及其转换、顺序结构、分支结构、循环结构、循环控制语句、字符串类型、列表类型、元组类型、字典类型、集合类型、函数的定义与使用、函数调用与作用域、函数的高级应用、质数、倍数与余数......