LeetCode 3272.统计好整数的数目:枚举+排列组合+哈希表
【LetMeFly】3272.统计好整数的数目:枚举+排列组合+哈希表
力扣题目链接:https://leetcode.cn/problems/find-the-count-of-good-integers/
给你两个 正 整数 n 和 k 。
如果一个整数 x 满足以下条件,那么它被称为 k 回文 整数 。
x是一个 回文整数 。x能被k整除。
如果一个整数的数位重新排列后能得到一个 k 回文整数 ,那么我们称这个整数为 好 整数。比方说,k = 2 ,那么 2020 可以重新排列得到 2002 ,2002 是一个 k 回文串,所以 2020 是一个好整数。而 1010 无法重新排列数位得到一个 k 回文整数。
请你返回 n 个数位的整数中,有多少个 好 整数。
注意 ,任何整数在重新排列数位之前或者之后 都不能 有前导 0 。比方说 1010 不能重排列得到 101 。
示例 1:
输入:n = 3, k = 5
输出:27
解释:
部分好整数如下:
- 551 ,因为它可以重排列得到 515 。
- 525 ,因为它已经是一个 k 回文整数。
示例 2:
输入:n = 1, k = 4
输出:2
解释:
两个好整数分别是 4 和 8 。
示例 3:
输入:n = 5, k = 6
输出:2468
提示:
1 <= n <= 101 <= k <= 9
解题方法:枚举+排列组合+哈希表
我们可以枚举所有长度为 n n n的数字回文字符串。对于一个回文串,如果其对应整数能够被 k k k整除,则这个字符串的所有排列都能被 k k k整除。
问题就转化为了以下三个:
-
如何枚举所有长度为 n n n的数字回文串?
我们可以枚举字符串的前半部分,然后反转得到后半部分并拼接,就得到了回文字符串。
具体的,我们可以从 [ 1 0 ⌊ n − 1 2 ⌋ , 1 0 ⌊ n − 1 2 ⌋ + 1 ) [10^{\lfloor\frac{n-1}2\rfloor}, 10^{\lfloor\frac{n-1}2\rfloor+1}) [10⌊2n−1⌋,10⌊2n−1⌋+1)枚举前半字符串,若 n n n为奇数则包含中间位置元素。
-
一个“k回文整数字符串”有多少个排列?多少个字符串重新排列后能得到这个字符串?
我们分别统计字符串中每个数字出现了多少次,假设字符串长度为 n n n。
首先计算第一位有多少种可能,第一位不能为 0 0 0,因此方案数为 n − t i m e s [ 0 ] n-times[0] n−times[0];
接着计算其他位,其他的 n − 1 n-1 n−1个数字可以随便排列,其他位的方案数为 ( n − 1 ) ! (n-1)! (n−1)!。
由于其中可能存在重复元素,例如 121 121 121中有两个 1 1 1,这两个 1 1 1谁在前谁在后无法区分,只能有一种方案,所以要除以 2 ! 2! 2!。
总的方案数为: ( n − t i m e s [ 0 ] ) × ( n − 1 ) ! Π i = 0 9 t i m e s [ i ] \frac{(n-times[0])\times (n-1)!}{\Pi_{i=0}^{9}times[i]} Πi=09times[i](n−times[0])×(n−1)!。
-
如何保证每个排列不会被重复统计?
假设我已经统计过 1221 1221 1221的所有全排列了,那么我遇到 2112 2112 2112时就不能再统计 2112 2112 2112的所有全排列了,因为 1221 1221 1221和 2112 2112 2112的全排列时相同的。
如何做到?其实我们只需要使用一个哈希表,记录字符串 s s s排序后的字符串是否出现过就好了。
时空复杂度分析
- 时间复杂度 O ( 1 0 m × n log n ) O(10^{m}\times n\log n) O(10m×nlogn),其中 m = ⌊ n − 1 2 ⌋ m=\lfloor\frac{n-1}2\rfloor m=⌊2n−1⌋
- 空间复杂度 O ( 1 0 m × n ) O(10^m\times n) O(10m×n)
AC代码
C++
/** @Author: LetMeFly* @Date: 2025-04-12 07:51:15* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-04-12 09:25:01* @Description: AC,21.21%,93.94%*/
#if defined(_WIN32) || defined(__APPLE__)
#include "_[1,2]toVector.h"
#endif/*
1 -> 1-9
2 -> 1-9
3 -> 10->99
4 -> 10->99
5 -> 100->999
6 -> 100->999n -> [10^((n-1)/2-1), 10^((n-1)/2)-1)
*/
typedef long long ll;class Solution {
private:int k;unordered_set<string> visited;vector<int> factor;int times[10];void initFactor(int n) {factor.resize(n + 1);factor[0] = 1;for (int i = 1; i <= n; i++) {factor[i] = factor[i - 1] * i;}}bool ifVisited(string s) {sort(s.begin(), s.end());if (visited.count(s)) {return true;}visited.insert(s);return false;}bool isOk(string& s) {ll val = stoll(s);// printf("%s: %d\n", s.c_str(), val % k == 0); // *****return val % k == 0;};ll calc(string& s) {memset(times, 0, sizeof(times));for (char c : s) {times[c - '0']++;}ll ans = (s.size() - times[0]) * factor[s.size() - 1];for (int i = 0; i < 10; i++) {ans /= factor[times[i]];}return ans;}
public:ll countGoodIntegers(int n, int k) {initFactor(n);this->k = k;ll ans = 0;for (int start = pow(10, (n - 1) / 2), end = start * 10; start < end; start++) {string prefix = to_string(start), suffix = prefix.substr(0, prefix.size() - n % 2);reverse(suffix.begin(), suffix.end());string thisNum = prefix + suffix;if (isOk(thisNum) && !ifVisited(thisNum)) { // 注意ifVisited会将thisNum加入哈希表的话记得先判断isOk再判断ifVisited// printf("ans: %lld, calc(%s): %lld, ans = ans + calc(%s) = %lld\n", ans, thisNum.c_str(), calc(thisNum), thisNum.c_str(), ans + calc(thisNum)); // ****ans += calc(thisNum);}}return ans;}
};
Python
'''
Author: LetMeFly
Date: 2025-04-12 09:44:25
LastEditors: LetMeFly.xyz
LastEditTime: 2025-04-12 10:52:36
Description: 中间终中断了下
'''
from collections import Counterclass Solution:def isOk(self, s: str) -> bool:return int(s) % self.k == 0def ifVisited(self, s: str) -> bool:s = ''.join(sorted(s))if s in self.visited:return Trueself.visited.add(s)return Falsedef calc(self, s: str) -> int:times = Counter(s)ans = (len(s) - times['0']) * self.factor[len(s) - 1]for _, val in times.items():ans //= self.factor[val]return ansdef countGoodIntegers(self, n: int, k: int) -> int:self.k = kself.factor = [1] * (n + 1)for i in range(1, n + 1):self.factor[i] = self.factor[i - 1] * iself.visited = set()base = pow(10, (n - 1) // 2)ans = 0for i in range(base, base * 10):prefix = str(i)s = prefix + prefix[::-1][n % 2:]if self.isOk(s) and not self.ifVisited(s):ans += self.calc(s)return ans
Java
/** @Author: LetMeFly* @Date: 2025-04-12 10:53:42* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-04-12 11:13:08*/
import java.util.Set;
import java.util.HashSet;
// import java.lang.StringBuilder; // 默认自动导入 无需手动导入
import java.util.Arrays;class Solution {private int k;private int[] factor;private Set<String> visited = new HashSet<>();private boolean isOk(String s) {return Long.parseLong(s) % k == 0;}private boolean ifVisited(String s) {char[] array = s.toCharArray();Arrays.sort(array);String sorted = new String(array);return !visited.add(sorted);}private long calc(String s) {int[] times = new int[10];for (char c : s.toCharArray()) {times[c - '0']++;}long ans = (s.length() - times[0]) * factor[s.length() - 1];for (int i = 0; i < 10; i++) {ans /= factor[times[i]];}return ans;}public long countGoodIntegers(int n, int k) {this.k = k;factor = new int[n + 1];factor[0] = 1;for (int i = 1; i <= n; i++) {factor[i] = factor[i - 1] * i;}long ans = 0;for (int from = (int)Math.pow(10, (n - 1) / 2), to = from * 10; from < to; from++) {String prefix = String.valueOf(from);String suffix = new StringBuilder(prefix).reverse().substring(n % 2);String s = prefix + suffix;if (isOk(s) && !ifVisited(s)) {ans += calc(s);}}return ans;}
}/*
API:java 子字符串
反转字符串
整数转字符串
字符串拼接
字符串转整数
*/
Go
/** @Author: LetMeFly* @Date: 2025-04-12 11:14:05* @LastEditors: LetMeFly.xyz* @LastEditTime: 2025-04-12 11:40:36* @Description: AC,25.00%,75.00%,一遍过*/
package mainimport ("math""strconv""sort""strings"
)type solution3273 struct{n, k intfactor []intvisited map[string]bool
}func init3273(n int, k int) *solution3273 {ans := &solution3273{n: n,k: k,factor: make([]int, n + 1),visited : map[string]bool{},}ans.factor[0] = 1for i := 1; i <= n; i++ {ans.factor[i] = ans.factor[i - 1] * i}return ans
}func (t* solution3273) isOk(s string) bool {val, _ := strconv.Atoi(s)return val % t.k == 0
}func (t* solution3273) ifVisited(s string) bool {array := strings.Split(s, "")sort.Strings(array)s = strings.Join(array, "")if t.visited[s] {return true}t.visited[s] = truereturn false
}func (t* solution3273) calc(s string) (ans int64) {times := [10]int{}for i, _ := range s {times[s[i] - '0']++}ans = int64(t.n - times[0]) * int64(t.factor[t.n - 1])for _, v := range times {ans /= int64(t.factor[v])}return
}func (t* solution3273) getFullS(prefix string) string {suffix := []byte(prefix)if t.n % 2 == 1 {suffix = suffix[:len(suffix) - 1]}for i := 0; i < len(suffix) / 2; i++ {suffix[i], suffix[len(suffix) - i - 1] = suffix[len(suffix) - i - 1], suffix[i]}return prefix + string(suffix)
}func countGoodIntegers(n int, k int) (ans int64) {solution := init3273(n, k)from := int(math.Pow10((n - 1) / 2))to := from * 10for i := from; i < to; i++ {s := solution.getFullS(strconv.Itoa(i))if solution.isOk(s) && !solution.ifVisited(s) {ans += solution.calc(s)}}return
}
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源
相关文章:
LeetCode 3272.统计好整数的数目:枚举+排列组合+哈希表
【LetMeFly】3272.统计好整数的数目:枚举排列组合哈希表 力扣题目链接:https://leetcode.cn/problems/find-the-count-of-good-integers/ 给你两个 正 整数 n 和 k 。 如果一个整数 x 满足以下条件,那么它被称为 k 回文 整数 。 x 是一个…...
Linux中的tar -P选项
tar -P选项 Linux中的tar命令可用于文件和目录的归档以及压缩解压缩。而其中的-P选项是什么含义呢?下面我们就来看一看 1、不添加-P选项 对于如下压缩命令: tar -czvf pkg.tar.gz /opt/software执行该命名,控制台首行输出将会提示…...
Linux目录探秘:文件系统的核心架构
引言 Linux文件系统就像一棵精心设计的大树🌳,每个分支都有其特定的用途和规范。与Windows不同,Linux采用单一的目录结构,所有设备、分区和网络资源都挂载在这个统一的目录树下。本文将带你深入探索Linux目录结构的奥秘ÿ…...
国标GB28181视频平台EasyCVR如何搭建汽车修理厂远程视频网络监控方案
一、背景分析 近年我国汽车保有量持续攀升,与之相伴的汽车保养维修需求也逐渐提高。随着社会经济的发展,消费者对汽车维修服务质量的要求越来越高,这使得汽车维修店的安全防范与人员管理问题面临着巨大挑战。 多数汽车维修店分布分散&#…...
python【标准库】multiprocessing
文章目录 介绍多进程Process 创建子进程共享内存数据多进程通信Pool创建子进程多进程案例多进程注意事项介绍 python3.10.17版本multiprocessing 是一个多进程标准模块,使用类似于threading模块的API创建子进程,充分利用多核CPU来并行处理任务。提供本地、远程的并发,高效避…...
南墙WAF非标端口防护实战解析——指定端口安全策略深度剖析
本文系统解析非标端口DDoS攻击防护难点,重点阐述南墙WAF在指定端口防御中的技术突破。通过某金融机构真实攻防案例,结合Gartner最新防御架构模型,揭示如何构建基于智能流量建模的精准防护体系,为金融、政务等关键领域提供可落地的…...
PostIn安装及入门教程
PostIn是一款国产开源免费的接口管理工具,包含项目管理、接口调试、接口文档设计、接口数据MOCK等模块,支持常见的HTTP协议、websocket协议等,支持免登陆本地接口调试,本文将介绍如何快速安装配置及入门使用教程。 1、安装 私有…...
spring cloud微服务API网关详解及各种解决方案详解
微服务API网关详解 1. 核心概念 定义:API网关作为微服务的统一入口,负责请求路由、认证、限流、监控等功能,简化客户端与后端服务的交互。核心功能: 路由与转发:将请求分发到对应服务。协议转换:HTTP/HTTP…...
最新版PhpStorm超详细图文安装教程,带补丁包(2025最新版保姆级教程)
目录 前言 一、PhpStorm最新版下载 二、PhpStorm安装 三、PhpStorm补丁 四、运行PhpStorm 前言 PhpStorm 是 JetBrains 公司推出的 专业 PHP 集成开发环境(IDE),专为提升 PHP 开发效率设计。其核心功能包括智能代码补全、实时语法错误检…...
FileInputStream 详解与记忆方法
FileInputStream 详解与记忆方法 一、FileInputStream 核心概念 FileInputStream 是 Java 中用于从文件读取原始字节的类,继承自 InputStream 抽象类。 1. 核心特点 特性说明继承关系InputStream → FileInputStream数据单位字节(8bit)用…...
【计算机网络】同步操作 vs 异步操作:核心区别与实战场景解析
📌 引言 在网络通信和分布式系统中,**同步(Synchronous)和异步(Asynchronous)**是两种基础却易混淆的操作模式。本文将通过代码示例、生活类比和对比表格,帮你彻底理解它们的区别与应用场景。 1…...
linux kernel arch 目录介绍
一:arch 目录 二:常用arch...
ES6变量声明:let、var、const全面解析
一、引言 ECMAScript 6(简称 ES6)的发布为 JavaScript 带来了许多革命性的变化,其中变量声明方式的更新尤为重要。let、var和const成为开发者日常编码中频繁使用的关键字。 本文将深入解析这三种声明方式的核心特性、区别及最佳实践ÿ…...
Linux 入门八:Linux 多进程
一、概述 1.1 什么是进程? 在 Linux 系统中,进程是程序的一次动态执行过程。程序是静态的可执行文件,而进程是程序运行时的实例,系统会为其分配内存、CPU 时间片等资源。例如,输入 ls 命令时,系统创建进程…...
单调栈 —— 1.基本概念与核心算法
1. 基本概念 1.1 知识预备 在理解单调栈之前,我们需要先掌握两个基础概念:栈(Stack) 和 单调性(Monotonicity)。 什么是栈(Stack) 栈是一种**后进先出(LIFO, Last-In…...
工程师 - 场效应管分类
What Are the Different Types of FETs? Pulse Octopart Staff Jul 31, 2021 Field effect transistors (FETs) are today’s workhorses for digital logic, but they enjoy plenty of applications outside of digital integrated circuits, everything from motor driver…...
用infoNCE微调Embedding模型
infoNCE 代码1:(样本格式为query_n个positive_n个hardnegative) PairwiseModel并不是模型,而是连接model和loss的一个包装类。 PairwiseModel接收两种类型样本 【query pos pair】or【query pos neg triplet】。 CrossEntropy…...
Debezium报错处理系列之第128篇:增量快照报错java.lang.OutOfMemoryError: Java heap space
Debezium报错处理系列之第128篇:增量快照报错java.lang.OutOfMemoryError: Java heap space 一、完整报错二、错误原因三、解决方法Debezium从入门到精通系列之:研究Debezium技术遇到的各种错误解决方法汇总: Debezium从入门到精通系列之:百篇系列文章汇总之研究Debezium技…...
AI——使用pandas
文章目录 1、pandas介绍2、为什么使用pandas3、pandas的数据结构1、Series2、DataFrame3、MultiIndex 4、pandas基本数据操作1、索引操作2、赋值操作3、排序4、算术运算5、逻辑运算6、逻辑运算函数7、统计函数8、累计统计函数9、自定义运算 5、pandas读取文件和存储1、csv文件2…...
SMT贴片组装工艺优化与高效生产
内容概要 现代SMT贴片组装工艺的优化与高效生产涉及多维度技术协同,其核心在于构建精密可控的制造体系。本文系统梳理了从焊接参数调控到智能检测部署的全链路关键环节,重点解析影响生产效能的核心变量及其相互作用机制。通过对比不同贴装设备的速度-精…...
2025认证杯挑战赛B题【 谣言在社交网络上的传播 】原创论文讲解(含完整python代码)
大家好呀,从发布赛题一直到现在,总算完成了认证杯数学中国数学建模网络挑战赛第一阶段B题目谣言在社交网络上的传播完整的成品论文。 本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半…...
用docker容器创建属于自己的一方小世界!容器中,盖周天之变,化吾为王~
用docker容器创建属于自己的一方小世界!容器中,盖周天之变,化吾为王~ 分别查看用户id和组id。 命令: 1、id -u 2、id -g 创建并运行容器 docker run -d -p 31404:22 -v /home/liub:/home -v /data:/app/data --user 1004:1004 --…...
vue拓扑图组件
vue拓扑图组件 介绍技术栈功能特性快速开始安装依赖开发调试构建部署 使用示例演示截图组件源码 介绍 一个基于 Vue3 的拓扑图组件,具有以下特点: 1.基于 vue-flow 实现,提供流畅的拓扑图展示体验 2.支持传入 JSON 对象自动生成拓扑结构 3.自…...
前端防御性编程
关于防御性编程 你是否遇到过,接口请求失败或者返回数据错误,导致系统白屏或者前端自身写的代码存在一些缺陷,导致整个系统不够健壮,从而导致系统白屏 常见的问题与防范 最常见的问题 访问了null或者undefined的属性 null.a …...
Linux服务器网卡深度解析:从ifconfig输出到生产环境性能调优实战
Linux服务器网卡深度解析:从ifconfig输出到生产环境性能调优实战 Linux服务器网卡深度解析:从ifconfig输出到生产环境性能调优实战一、背景二、生产环境的服务器部署情况三、拆解一个真实的 ifconfig 输出1、先看 MAC 地址2、再看设备的 interrupt 和 me…...
【愚公系列】《Python网络爬虫从入门到精通》048-验证码识别(滑动拼图验证码)
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
SpringBoot分布式项目中实现智能邮件提醒系统
一、应用场景与需求分析 在电商、OA、客服等系统中,邮件提醒是用户触达的重要方式。本文针对以下典型需求进行方案设计: 多类型支持:订单超时、服务到期、待办通知等场景动态内容:支持纯文本/HTML/模板引擎内容格式智能重发:24小时未处理自动升级提醒级别高可用性:分布式…...
对shell脚本敏感命令进行加密执行
我要加密这条命令:rm /root/scripty.sh 如何利用openssl aes-256-cbc 实现加密和解密,并执行命令 加密、解密并执行命令的完整流程 以下是使用 openssl aes-256-cbc 加密命令 rm /root/scripty.sh,解密并执行的详细步骤: 1. 加密…...
《嵌套调用与链式访问:C语言中的函数调用技巧》
🚀个人主页:BabyZZの秘密日记 📖收入专栏:C语言 🌍文章目入 一、嵌套调用(一)定义(二)实现方式(三)优点(四)缺点 二、链式…...
Python-控制语句
控制语句 控制语句和逻辑思维 控制语句:把语句组合成能完成一定功能的小逻辑模块分类:顺序、选择、循环“顺序结构”:代表“先执行a,再执行b”的逻辑“条件判断结构”:代表“如果…,则…”的逻辑“循环结构”:代表“如果…则重复执行…”的逻辑条件判断结构 选择结构通…...
