2023-07-11:给定正整数 n,

返回在 [1, n] 范围内具有 至少 1 位 重复数字的正整数的个数。

输入:n = 100。

输出:10。

答案2023-07-11:

函数的主要思路如下:

1.若n小于等于10,则直接返回0,因为在[1, 10]范围内不存在重复数字的情况。

2.计算n的位数和偏移量。首先计算n的位数和一个偏移量offset,其中偏移量初始值为1,算法通过迭代计算tmp = n / 10的商,直到商为0为止,每次迭代位数加1,偏移量乘以10。

3.计算每个长度的非重复数字的个数。通过一个辅助函数numAllLength计算不同位数下,每个位都是唯一的数字的个数,并将其累加到变量noRepeat上。

4.计算长度为len的非重复数字的个数。当长度小于等于10时,通过包含位运算的算法进行计算,具体步骤如下:

4.1.初始化一个十进制数status为2^10-1,二进制表示为0b1111111111,用于标记当前数字的可用状态,初始状态为每位都可用。(1表示不可用,0表示可用)

4.2.根据n的位数和偏移量计算出n除以offset的商,即当前数字的最高位first。

4.3.将分三种情况:

4.3.1.若first大于0,则对于0到first-1的数字cur,如果status的第cur位为1,说明该数字可用,将offset/10和status的第cur位取反异或,并调用辅助函数numberRest计算剩余位和可用状态下的数字个数,将结果累加到变量ans上。

4.3.2.若first等于0,则直接跳过该步骤。

4.3.3.若first在0到9之间,则如果status的第first位为1,说明该数字可用,将offset/10和status的第first位取反异或,并调用递归函数process计算剩余位和可用状态下的数字个数,将结果累加到变量ans上。

5.最后的结果为n加1减去noRepeat,即在[1, n]范围内至少有1位重复数字的正整数的个数。

该代码在给定正整数n的范围内采用了一种比较高效的算法,通过一系列的位运算和迭代计算,找出了每个位数下非重复数字的个数,然后根据n的位数和偏移量来计算在该位数下包含至少1位重复数字的正整数的个数,并将它们相加得出最终结果。

该代码的时间复杂度为O(log10(n) * 2 ^ 10),其中n是输入的正整数。主要消耗时间的是计算每个位数下非重复数字的个数,该计算的时间复杂度为O(log10(n)),而计算每个长度为len的非重复数字的个数的时间复杂度为O(2 ^ len)。因为长度为len的数字有2 ^ len个,所以计算每个长度为len的非重复数字的个数的时间复杂度为O(2 ^ len)。

该代码的空间复杂度为O(1),因为它只使用了常量级的额外空间来保存一些临时变量,不随输入规模的增长而增加。

go完整代码如下:

package main

import (
"fmt"
) func numDupDigitsAtMostN(n int) int {
if n <= 10 {
return 0
} // Calculate the length of n and the offset
len, offset := 1, 1
tmp := n / 10
for tmp > 0 {
len++
offset *= 10
tmp /= 10
} // Calculate the count of non-repeating numbers of each length
noRepeat := 0
for i := 1; i < len; i++ {
noRepeat += numAllLength(i)
} // Calculate the count of non-repeating numbers for length len
if len <= 10 {
status := 0b1111111111
noRepeat += ((n / offset) - 1) * numberRest(offset/10, status^1)
noRepeat += process(offset/10, status^(1<<(n/offset)), n)
} return n + 1 - noRepeat
} // Returns the count of numbers where each digit is unique for a given length
func numAllLength(len int) int {
if len > 10 {
return 0
}
if len == 1 {
return 10
} ans, cur := 9, 9
for len--; len > 0; len-- {
ans *= cur
cur--
} return ans
} // Returns the count of numbers where the remaining digits are unique
func process(offset, status, n int) int {
if offset == 0 {
return 1
} ans := 0
first := (n / offset) % 10
for cur := 0; cur < first; cur++ {
if (status & (1 << cur)) != 0 {
ans += numberRest(offset/10, status^(1<<cur))
}
} if (status & (1 << first)) != 0 {
ans += process(offset/10, status^(1<<first), n)
} return ans
} // Returns the count of numbers with remaining length and available digits
func numberRest(offset, status int) int {
c := hammingWeight(status)
ans := 1
for offset > 0 {
ans *= c
c--
offset /= 10
}
return ans
} // Returns the number of set bits (1s) in a binary representation
func hammingWeight(n int) int {
n = (n & 0x55555555) + ((n >> 1) & 0x55555555)
n = (n & 0x33333333) + ((n >> 2) & 0x33333333)
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f)
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff)
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff)
return n
} func main() {
n := 1000
result := numDupDigitsAtMostN(n)
fmt.Println(result)
}

rust完整代码如下:

pub fn num_dup_digits_at_most_n(n: i32) -> i32 {
if n <= 10 {
return 0;
} let len = get_length(n);
let mut offset = 1;
let mut tmp = n / 10;
while tmp > 0 {
offset *= 10;
tmp /= 10;
} let mut no_repeat = 0;
for i in 1..len {
no_repeat += num_all_length(i);
} if len <= 10 {
let status = 0b1111111111;
no_repeat += ((n / offset) - 1) * number_rest(offset / 10, status ^ 1);
no_repeat += process(offset / 10, status ^ (1 << (n / offset)), n);
} n + 1 - no_repeat
} fn get_length(n: i32) -> i32 {
let mut len = 1;
let mut tmp = n / 10;
while tmp > 0 {
len += 1;
tmp /= 10;
}
len
} fn num_all_length(len: i32) -> i32 {
if len > 10 {
return 0;
}
if len == 1 {
return 10;
}
let mut ans = 9;
let mut cur = 9;
let mut len = len - 1;
while len > 0 {
ans *= cur;
cur -= 1;
len -= 1;
}
ans
} fn process(offset: i32, status: i32, n: i32) -> i32 {
if offset == 0 {
return 1;
} let mut ans = 0;
let first = (n / offset) % 10;
for cur in 0..first {
if (status & (1 << cur)) != 0 {
ans += number_rest(offset / 10, status ^ (1 << cur));
}
} if (status & (1 << first)) != 0 {
ans += process(offset / 10, status ^ (1 << first), n);
} ans
} fn number_rest(offset: i32, status: i32) -> i32 {
let mut c = hamming_weight(status);
let mut ans = 1;
let mut offset = offset;
while offset > 0 {
ans *= c;
c -= 1;
offset /= 10;
}
ans
} fn hamming_weight(mut n: i32) -> i32 {
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
n
} fn main() {
let n = 1000;
let result = num_dup_digits_at_most_n(n);
println!("Result: {}", result);
}

c++完整代码如下:

#include <iostream>
#include <cmath> int numAllLength(int len); int process(int offset, int status, int n); int numberRest(int offset, int status); int hammingWeight(int n); int numDupDigitsAtMostN(int n) {
if (n <= 10) {
return 0;
}
int len = 1;
int offset = 1;
int tmp = n / 10;
while (tmp > 0) {
len++;
offset *= 10;
tmp /= 10;
}
int noRepeat = 0;
for (int i = 1; i < len; i++) {
noRepeat += numAllLength(i);
}
if (len <= 10) {
int status = 0b1111111111;
noRepeat += ((n / offset) - 1) * numberRest(offset / 10, status ^ 1);
noRepeat += process(offset / 10, status ^ (1 << (n / offset)), n);
}
return n + 1 - noRepeat;
} int numAllLength(int len) {
if (len > 10) {
return 0;
}
if (len == 1) {
return 10;
}
int ans = 9;
int cur = 9;
while (--len > 0) {
ans *= cur;
cur--;
}
return ans;
} int process(int offset, int status, int n) {
if (offset == 0) {
return 1;
}
int ans = 0;
int first = (n / offset) % 10;
for (int cur = 0; cur < first; cur++) {
if ((status & (1 << cur)) != 0) {
ans += numberRest(offset / 10, status ^ (1 << cur));
}
}
if ((status & (1 << first)) != 0) {
ans += process(offset / 10, status ^ (1 << first), n);
}
return ans;
} int numberRest(int offset, int status) {
int c = hammingWeight(status);
int ans = 1;
while (offset > 0) {
ans *= c;
c--;
offset /= 10;
}
return ans;
} int hammingWeight(int n) {
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
return n;
} int main() {
int n = 1000;
int result = numDupDigitsAtMostN(n);
std::cout << "Result: " << result << std::endl;
return 0;
}

c完整代码如下:

#include <stdio.h>
#include <stdbool.h> int numAllLength(int len); int process(int offset, int status, int n); int numberRest(int offset, int status); int hammingWeight(int n); int numDupDigitsAtMostN(int n) {
if (n <= 10) {
return 0;
} int len = 1;
int offset = 1;
int tmp = n / 10;
while (tmp > 0) {
len++;
offset *= 10;
tmp /= 10;
} int noRepeat = 0;
for (int i = 1; i < len; i++) {
noRepeat += numAllLength(i);
} if (len <= 10) {
int status = 0b1111111111;
noRepeat += ((n / offset) - 1) * numberRest(offset / 10, status ^ 1);
noRepeat += process(offset / 10, status ^ (1 << (n / offset)), n);
} return n + 1 - noRepeat;
} int numAllLength(int len) {
if (len > 10) {
return 0;
}
if (len == 1) {
return 10;
} int ans = 9;
int cur = 9;
while (--len > 0) {
ans *= cur;
cur--;
} return ans;
} int process(int offset, int status, int n) {
if (offset == 0) {
return 1;
}
int ans = 0;
int first = (n / offset) % 10; for (int cur = 0; cur < first; cur++) {
if ((status & (1 << cur)) != 0) {
ans += numberRest(offset / 10, status ^ (1 << cur));
}
} if ((status & (1 << first)) != 0) {
ans += process(offset / 10, status ^ (1 << first), n);
} return ans;
} int numberRest(int offset, int status) {
int c = hammingWeight(status);
int ans = 1; while (offset > 0) {
ans *= c;
c--;
offset /= 10;
} return ans;
} int hammingWeight(int n) {
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff); return n;
} int main() {
int n = 1000;
int result = numDupDigitsAtMostN(n);
printf("Result: %d\n", result);
return 0;
}

2023-07-11:给定正整数 n, 返回在 [1, n] 范围内具有 至少 1 位 重复数字的正整数的个数。 输入:n = 100。 输出:10。的更多相关文章

  1. 输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。

    题目描述 输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数. 输入描述: 输入一个int型整数 输出描述: 按照从右向左的阅读顺序,返回一个不含重复数字的新的整数 输入例子 ...

  2. JAVA 之 每日一记 之 算法( 给定一个正整数,返回它在 Excel 表中相对应的列名称。 )

    题目: 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -& ...

  3. 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。

    谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...

  4. 02-Nov-2017 07:11:56.475 信息 [http-nio-8080-exec-10] com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource. Initializing c3p0 pool...

    报错: 02-Nov-2017 07:11:56.475 信息 [http-nio-8080-exec-10] com.mchange.v2.c3p0.impl.AbstractPoolBackedD ...

  5. PHP根据传入的经纬度,和距离范围,返回所有在距离范围内的经纬度的取值范围

    /** * 根据传入的经纬度,和距离范围,返回所有在距离范围内的经纬度的取值范围 * @param float $lng 经度 * @param float $lat 纬度 * @param floa ...

  6. JAVA 基础编程练习题11 【程序 11 求不重复数字】

    11 [程序 11 求不重复数字] 题目:有 1.2.3.4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位.十位.个位的数字都是 1.2.3.4.组成所有的排列后 ...

  7. Excel表列名称(给定一个正整数,返回它在 Excel 表中相对应的列名称。)

    例如, 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -> AB ... 示例 1: 输入: 1 输出: "A ...

  8. C++11获取线程的返回值

    C++11 std::future and std::promise 在许多时候,我们会有这样的需求--即我们想要得到线程返回的值. 但是在C++11 多线程中我们注意到,std::thread对象会 ...

  9. 2016/07/11 PHP接口的介绍与实现

        接口定义了实现某种服务的一般规范,声明了所需的函数和常量,但不指定如何实现.之所以不给出实现的细节,是因为不同的实体可能需要用不同的方式来实现公共的方法定义.关键是要建立必须实现的一组一般原则 ...

  10. 【纪中集训】2019.07.11【NOIP提高组】模拟 B 组TJ

    Preface 今天的B组题确实比A组难多了... T1 Description 有一个长为\(n(n\in[1,2*10^5])\)的01串,有\(m(m\in[1,10^5])\)个限制\(a_i ...

随机推荐

  1. 脚本:Oracle巡检html版

    做一个日常巡检oracle数据库的脚本,生成一个html版本,简介方便查看 check_db.sql 1.数据库情况 2.数据文件及表空间情况 3.数据库性能问题 4.加入邮件,定期发送到邮箱 发件语 ...

  2. YII2.0框架分页

    这篇文章主要介绍了Yii分页用法,以实例形式详细分析了比较常见的几种分页方法及其应用特点,非常具有实用价值,需要的朋友可以参考下: 在这里我主要联查的 book 表和 book_press 两张表进行 ...

  3. 【SSM项目】尚筹网(四)JWT以及基于拦截器的前后端分离登录验证

    引入JWT前后端交互 JsonWebToken(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准.JWT就是一段字符串,分为三段[头部.载荷.签证]. 1 后端配置 1.1 ...

  4. Hyperledger Fabric 使用 CouchDB 和复杂智能合约开发

    前言 在上个实验中,我们已经实现了简单智能合约实现及客户端开发,但该实验中智能合约只有基础的增删改查功能,且其中的数据管理功能与传统 MySQL 比相差甚远.本文将在前面实验的基础上,将 Hyperl ...

  5. jquery实现一个网页同时调用多个倒计时

    <div class="time countdown_1" data-time="1449429731"> <span class=" ...

  6. Albert理论详解:用矩阵分解与跨层参数共享减少参数量

    1.介绍 Albert是Bert的一个变种,它在Bert的基础上减少了参数量,使整个模型更加的"轻量化",同时也保持了Bert的性能,但值得注意的是,Albert虽然显著地减少了参 ...

  7. C# 无需管理员权限提示,操作C盘文件

    在C盘创建.移动文件,如果当前不是管理员身份,是没办法直接操作. 如果当前程序有管理员权限,那可以直接操作. 但是,添加管理员权限启动,会弹出用户确认提示框. 在某些场景下,其实是不想让用户看到这样的 ...

  8. 机器学习06-(支持向量机SVM、网格搜索、文本分词、词袋模型、词频、文本分类-主题识别)

    机器学习-06 机器学习-06 支持向量机(SVM) 支持向量机原理 网格搜索 情感分析 文本分词 词袋模型 词频(TF) 文档频率(DF) 逆文档频率(IDF) 词频-逆文档频率(TF-IDF) 文 ...

  9. 2020-11-07:已知一个正整数数组,两个数相加等于N并且一定存在,如何找到两个数相乘最小的两个数?

    福哥答案2020-11-07: 1.哈希法.2.排序+双指针夹逼. golang代码如下: package main import ( "fmt" "sort" ...

  10. 2021-09-08:每一个项目都有三个数,[a,b,c]表示这个项目a和b乐队参演,花费为c。每一个乐队可能在多个项目里都出现了,但是只能被挑一次。nums是可以挑选的项目数量,所以一定会有nums

    2021-09-08:每一个项目都有三个数,[a,b,c]表示这个项目a和b乐队参演,花费为c.每一个乐队可能在多个项目里都出现了,但是只能被挑一次.nums是可以挑选的项目数量,所以一定会有nums ...