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

news2024/7/6 20:10:22

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;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/743343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

漏洞复现 || SolarView Compact 存在任意命令执行漏洞(CVE-2023-23333)

免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使…

k8s+springboot+CronJob 定时任务部署

kubernetesspringbootCronJob 定时任务配置如下代码&#xff1a; cronjob.yaml k8s 文件 apiVersion: batch/v1 kind: CronJob metadata:name: k8s-springboot-demonamespace: rz-dt spec:failedJobsHistoryLimit: 3 #执行失败job任务保留数量successfulJobsHistoryLimit: 5 …

etcd的使用

什么是etcd ETCD是一个分布式、可靠的key-value存储的分布式系统&#xff0c;用于存储分布式系统中的关键数据&#xff1b;当然&#xff0c;它不仅仅用于存储&#xff0c;还提供配置共享及服务发现&#xff1b;基于Go语言实现 。 etcd的特点 完全复制&#xff1a;集群中的每…

Spring Boot 系列1 -- 概念、创建和使用

目录 1. 什么是Spring Boot? 2. Spring Boot 的优点 3. Spring Boot 项目的创建 3.1 使用IDEA创建 3.2 网页版创建 4. 项目目录和项目运行 4.1 项目目录 4.2 运行项目 4.3 使用Spring Boot项目实现网页输出Hello World 5. 路径问题 1. 什么是Spring Boot? Spring …

【vue+vant使用请求loading】【vant如何关闭Toast】

vuevant使用请求loading 文档&#xff1a;https://vant-contrib.gitee.io/vant/v2/#/zh-CN/toast 需求&#xff1a;目前需求是在请求中使用toast-loading&#xff0c;请求完成后关闭这个toast&#xff1b; 问题&#xff1a;vant如何关闭toast呢&#xff1f; 解决&#xff1a…

【UE4 C++】05-添加组件

在“SCharacter.h”中添加如下代码&#xff0c;从而为“SCharacter”添加弹簧臂和摄像机组件。 在“SCharacter.cpp”中添加如下代码 重新生成解决方案 打开虚幻编辑器&#xff0c;此时在视口中可以看到新添加的摄像机组件&#xff0c;摄像机处于世界坐标原点&#xff0c;并不会…

VisProg解析:根据自然语言指令解决复杂视觉任务

VisProg&#xff1a;根据自然语言指令解决复杂视觉任务 1. 介绍 VisProg 是一种神经符号系统&#xff0c;可以根据自然语言指令解决复杂的组合视觉任务。VisProg 使用 GPT3 的上下文学习能力来生成 Python 程序&#xff0c;然后执行这些程序以获得解决方案和全面且可解释的基…

前端学习——css盒子模型、css3新特性、伪类、布局0711TODO

样式还是得具体使用才能理解&#xff0c;不然会忘记也理解不透彻&#xff1b;还有定位&#xff0c;元素溢出&#xff0c;浮动&#xff0c;布局水平&垂直对齐&#xff1a; css3新特性 1过渡 2 动画 3 2D、3D转换 伪类 三种定位方式 弹性布局/栅格布局

VS+QT+OpenCV+C++多线程多摄像头视频监控采集窗体

程序示例精选 VSQTOpenCV多线程多摄像头视频监控采集窗体 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<VSQTOpenCV多线程多摄像头视频监控采集窗体>>编写代码&#xff0c;代码…

【Matlab】智能优化算法_算数优化算法AOA

【Matlab】智能优化算法_算数优化算法AOA 1.背景介绍2.数学模型2.1 初始化阶段2.2 勘探阶段2.3 开采阶段 3.文件结构4.伪代码5.详细代码及注释5.1 AOA.m5.2 func_plot.m5.3 Get_F.m5.4 initialization.m5.5 main.m 6.运行结果7.参考文献 1.背景介绍 算术是数论的基本组成部分&a…

MySQL的表操作DML,DDL

建表 mysql> create table work(-> dept_id int(11) not null comment 部门号,-> staff_id int(11) not null comment 职工号,-> work_time date not null comment 工作时间,-> wage float(8.2) not null comment 工资,-> poli_face varchar(20) not null …

软考A计划-系统集成项目管理工程师-项目成本管理-中

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

如何在本地组策略编辑器中启用或禁用剪贴板历史记录

复制粘贴是我们大家都会做的事情,可能一天要做多次。但是,如果你需要一次又一次地复制同样的几件事,你该怎么办?如何在设备上复制内容? 从Windows 10版本17666开始,微软正在解决这一问题,并将剪贴板提升到一个新的水平,只需按下Win+V,你将获得全新的剪贴板体验。 你…

session共享问题和其他常见问题及解决方案

目录 1.shirospringboot中session的共享问题 1.1 如何解决session共享问题 2. 解决前端不支持cookie的效果 2.1.如何把sessionId放入请求头 2.2.重写DefaultWebSessionManager的方法 3.设置前端前置路由守卫 4.如何防止恶意重复登录 5.退出 6.获取当前登录用户的信息 …

jQuery根据数据动态创建表格:列固定,行超出滚动条,绑定td点击事件等

示例如图&#xff0c;代码如下: html: <div class"layui-row" id"avTableulL"><ul></ul></div><div id"avTableulR"><div id"avTableulT"><ul></ul></div><div id"avT…

【华为认证】HCIP-Datacom 2023最新题库

正在备考华为认证的小伙伴应该知道&#xff0c;除了理论知识外&#xff0c;刷题也相当重要&#xff0c;周工这里有一份HCIAHCIP-Datacom带解析的最新题库 点赞留言 即可领取。 1. &#xff08;多选题&#xff09;ISIS的Hello报文主要分为哪几种类型? A.P2P LAN IIH B.…

UnityVR--机械臂场景12-简单流水线应用4

目录 一. 手爪 二. 红外线传感器 三. 工件生成器 四. 总结 上一篇已经实现了机械臂各种动作的控制&#xff0c;本篇实现一下其余的组成部分&#xff0c;比如手爪、传感器和自动放置工件等。 一. 手爪 手爪的模型调整就不多说了&#xff0c;需要设置的是Rigidbody、Collide…

在Visual Studio Code里导出8266固件

1.编辑 .vscode目录下 arduion.json 添加 一个配置项output即输出目录.当然你不设置其它软固件一样会生成,只是就不知道你能不能找到了.我的配置如下 当然这个路径你想写什么 就是什么 . 2. 切换到 arduion的项目文件 xxxx.ino.点击vsc右上的验证 即可在上面设置的目录下找到…

Nginx系列之 一 入门

目录 一、Nginx概述 二、yum安装 三、nginx.conf配置文件详解 3.1 全局块 3.2 events 块 3.3 HTTP 块 四、Nginx 常用命令 五、Nginx代理 4.1 正向代理 4.2 反向代理 六、Nginx的Master-Worker模式 6.1 Master进程的作用是&#xff1f; 6.2 Worker进程的作用是&am…

Layui动态树详解

Layui动态树详解 一、什么是动态树形&#xff1f;二、Layui动态树形基本使用三、动态加载数据4.案列1.实体类2.dao方法3.子实现类4.jsp页面 前言 在前端开发过程中&#xff0c;树形控件是比较常用的控件之一。而Layui框架中&#xff0c;也提供了基于jQuery的树形控件。除了普通…