[LeetCode] 5933. k 镜像数字的和
一、摘要
本文介绍了一种通过模拟寻找十进制镜像数字,然后判断其对应的k进制表示是否也是镜像的方法。具体来讲即从小到大遍历10进制的镜像数字,然后对10进制镜像数字转为k进制,然后判断转为k进制后是否还满足镜像。题解5933【C++】 800ms 三道简单题的组合对本题已经有较为详细的解释,若读者对本文有所疑问,可以阅读题解5933【C++】 800ms 三道简单题的组合。
二、题解
本题主要分为三个小问题:
- 从小到大遍历10进制镜像数字;
- 将十进制镜像数字转为k进制表达;
- 判断k进制数字表达是否为镜像;
其中小问题2.可以通过求余得到;问题3.可以通过穷举k进制数字各位得到结果。本文将主要对问题1.进行介绍。
为了从小到大遍历10进制镜像数字,我们可以依次讨论不同长度(位数)的数字:
- 对于长度为1的所有10进制数字。所有数字都是镜像的(即数字1,2,3,4,5,6,7,8,9都是镜像的)。
- 对于长度为奇数的10进制数字。例如,长度为5的所有10进制数字,其中镜像数字从小到大一定是:10'0'01, 10'1'01, 10'2'01, ..., 11'0'11, 12'1'21, ..., 99'0'99, ..., 99'9'99。
可以看出,奇数长度的10进制镜像数字可以看成由pre+mid+suf三部分组成的(使用'符号分割的三部分),而且pre从10开始直到99,中间的mid对于任意pre都是从0到9,而suf正好是pre的反转。因此我们可以根据此规律从小到达求得长度为奇数的十进制镜像数字。 - 类似的,对于长度为偶数的十进制数字。例如长度为6的所有十进制数字,其中的镜像数字从小到大一定是:100'001, 101'101, 102'201,..., 999'999。
可以看出偶数长度的十进制镜像数字可以看成pre+suf两部分,而且pre从100开始一直到999,suf为pre的反转。因此我们也可以根据此规律从小到大求得长度为偶数的10进制镜像数字。
至此,对于不同长度的10进制数字,我们都可以根据相应的规律从小到大求得该长度范围内的镜像数字,然后再判断其转为k进制后是否依旧为镜像数字,找到题目要求的n个满足条件的数字即可。
代码如下:
class Solution {
public:
vector<long long> p = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000};
long long myPow(int n){
return p[n];
}
// 判读数字num的k进制表示是否为镜像
bool isPalindrome(long long num, int k){
string nums; // 注意!此处一定要使用string类型记录各位数字,使用vector<int>会超时
while(num){
nums.push_back(num%k);
num /= k;
}
int n = nums.size();
for(int i=0; i<n/2; i++){
if(nums[i]!=nums[n-1-i]){
return false;
}
}
return true;
}
long long kMirror(int k, int n) {
long long ans = 0;
long long num = 1;
int len = 1;
while(true){
if(len==1){ // 1,2,3,4,5,6,7,8,9
for(int num=1; num<=9; num++){
if(isPalindrome(num, k)){
ans += num;
n --;
if(n<=0){
return ans;
}
}
}
len ++;
}else if(len%2==1){ // 长度为奇数的所有十进制镜像数字
int half_len = len/2;
long long num;
long long mid;
long long suf;
long long min_lit = myPow(half_len-1); // 例如,对于长度为5的数字,pre从10开始遍历到99
long long max_lit = myPow(half_len);
for(long long pre=min_lit; pre<max_lit; pre++){
// 根据pre计算得到suf,suf是pre的反转
long long temp_pre = pre;
long long t = myPow(half_len-1);
suf = 0;
while(temp_pre){
suf += (temp_pre%10)*t;
temp_pre /=10;
t /=10;
}
for(int mid=0; mid<10;mid++){
num = pre*myPow(half_len+1)+mid*myPow(half_len)+suf;
if(isPalindrome(num, k)){
ans += num;
n --;
if(n<=0){
return ans;
}
}
}
}
len ++;
}else{ // 长度为偶数的所有十进制镜像数字
int half_len = len/2;
long long num;
long long suf;
long long min_lit = myPow(half_len-1); // 例如,对于长度为4的数字,pre从10开始遍历到99
long long max_lit = myPow(half_len);
for(long long pre=min_lit; pre<max_lit; pre++){
long long temp_pre = pre;
long long t = myPow(half_len-1);
suf = 0;
while(temp_pre){
suf += (temp_pre%10)*t;
temp_pre /=10;
t /=10;
}
num = pre*myPow(half_len)+suf;
if(isPalindrome(num, k)){
ans += num;
n --;
if(n<=0){
return ans;
}
}
}
len ++;
}
}
return ans;
}
};
三、参考
[LeetCode] 5933. k 镜像数字的和的更多相关文章
- [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...
- LeetCode:移除K位数字【402】
LeetCode:移除K位数字[402] 题目描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. nu ...
- Leetcode 402.移掉k位数字
移调k位数字 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : ...
- Leetcode 373.查找和最小的k对数字
查找和最小的k对数字 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找到和最小的 ...
- Java实现 LeetCode 440 字典序的第K小数字
440. 字典序的第K小数字 给定整数 n 和 k,找到 1 到 n 中字典序第 k 小的数字. 注意:1 ≤ k ≤ n ≤ 109. 示例 : 输入: n: 13 k: 2 输出: 10 解释: ...
- Java实现 LeetCode 402 移掉K位数字
402. 移掉K位数字 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示 ...
- Java实现 LeetCode 373 查找和最小的K对数字
373. 查找和最小的K对数字 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找 ...
- [LeetCode] Find K Closest Elements 寻找K个最近元素
Given a sorted array, two integers k and x, find the k closest elements to x in the array. The resul ...
- [Swift]LeetCode373. 查找和最小的K对数字 | Find K Pairs with Smallest Sums
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...
- 373 Find K Pairs with Smallest Sums 查找和最小的K对数字
给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k.定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2.找到和最小的 k 对数字 (u1,v1 ...
随机推荐
- 蓝鲸单机离线部署:app_mgr组件安装失败解决
之前在腾讯蓝鲸智云-单机离线部署测试中,遇到了几个安装问题,本文记录下3.2 app_mgr组件安装失败 的解决过程,因为这个问题卡了很久(可能也是因为笔者对python相关知识和蓝鲸产品不够熟悉), ...
- [Spring]Junit单元测试时取不到本地文件问题
Junit单元测试时取不到本地文件问题 问题 当使用Junit进行单元测试时,遇到了以下问题: 2022-10-24 16:13:19.902 [main] ERROR zonetop.gisboot ...
- Zabbix 配置笔记
Zabbix Server 安装参考 https://www.cnblogs.com/clsn/p/7885990.html 安装脚本 #!/bin/bash #clsn #设置解析 注意:网络条件较 ...
- 【Unity3D】广告牌特效
1 前言 广告牌特效是指:空间中的一个 2D 对象始终(或尽可能)面向相机,使得用户能够尽可能看清楚该 2D 物体.广告牌特效一共有以下 3 种: 正视广告牌:广告牌始终以正视图姿态面向相机,即广 ...
- 2022年3月核心库MySQL优化总结
2021年9月底到新公司,公司核心数据库,以前无专业DBA维护,问题多,隐患大,到2022年2月持续后,优化至今: 优化大项: 1,从1主3从,扩容到1主5从,将部分读放都另外新加从库 2,最大表 ...
- Oracle代码封装工具和DBMS_DDL包的使用
The WRAP Utility and the DBMS_DDL Package On occasion it is necessary to hide (obfuscate) your PL/SQ ...
- Vue+SpringBoot+ElementUI实战学生管理系统-9.教师管理模块
1.章节介绍 前一篇介绍了班级管理模块,这一篇编写教师管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.实现效果 教师列表 修改教师 4.模块 ...
- Springboot+Freemarker+Boostrap实现用户增删改查实战
说明 做java web用的2大模板语言分别是:thymeleaf和freemarker,thymeleaf前面已经用了很多了,所以今天用一下这个freemarker. 技术栈 springboot ...
- Mac技巧之苹果电脑上将一个软件进程的 CPU 占用率限制在指定范围内:cputhrottle
苹果电脑 Mac OS X 系统上,我们可以用 cputhrottle 这个免费工具,配合活动监视器和终端,把一个软件进程的 CPU 占用率限制在指定值(比如 20%)以内,以防止应为它 " ...
- C++ 多线程的错误和如何避免(7)
要以相同顺序获取多个锁 多线程在加锁解锁时,可能会出现死锁问题,比如, 线程 1 在加锁 mutex A 后,继续尝试获取 mutex B,而 mutex B 已经被线程 2 获取,而线程 2 在等待 ...