[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 ...
随机推荐
- 小知识:PDML的注意事项补充
关于PDML,之前在 并行,想说爱你不容易中的第一节就介绍过,今天在客户现场协助测试时又遇到几个有关PDML的问题,都蛮典型的,记录一下: 问题1:某存储过程报错ORA-12839. 查看该错误号说明 ...
- Java发送mail和C#发送mail
Java发送mail 阿里云邮箱,配置公司邮箱服务器,邮箱地址,授权码(运维同事提供,听说阿里云邮箱的授权码和密码一样),端口465,测试能发送. /** * 发送简单的文本邮件 */ public ...
- Hive数据导入与导出
数据导入 ● 本地文件导入 -- 本地文件导入(local) LOAD DATA local INPATH '/home/hadoop/sourceA.txt' INTO TABLE testA PA ...
- Atom N2600, N2800 安装 Ubuntu22.04 卡住的问题处理
问题描述 Atom N2600, N2800 的某些旧型号机器, 安装 Ubuntu 时在安装界面选择安装后, 启动过程中会卡住, 或者数秒即黑屏, 再无反应. 这个问题对于Debian系的其他发行版 ...
- 基于keras的残差网络
1 前言 理论上,网络层数越深,拟合效果越好.但是,层数加深也会导致梯度消失或梯度爆炸现象产生.当网络层数已经过深时,深层网络表现为"恒等映射".实践表明,神经网络对残差的学习比对 ...
- ElasticSearch入门安装与SpringBoot集成实战
介绍 Elasticsearch 是一个实时分布式搜索和分析引擎,一般用于全文搜索.结构化搜索,分析或者三者混用. 它的底层是基于Apache Lucene(TM)的开源搜索引擎,但是lucene只是 ...
- Springboot+Bootstrap实现增删改查实战
说明 最近有朋友问我有没有Springboot+Bootstrap实现增删改查的DEMO,当时没有,现在他来了! 实现效果 代码地址 https://gitee.com/indexman/bootst ...
- 修改mysql默认字符集和排序规则
1.查看当前数据库字符集和排序规则 命令如下: mysql> SHOW VARIABLES LIKE 'collation_%'; mysql> SHOW VARIABLES LIKE ' ...
- 【Android 逆向】【攻防世界】Ph0en1x-100
1. apk 安装到手机,老套路需要输入flag 2. jadx 打开apk,没有加壳 ...... public void onGoClick(View v) { String sInput = t ...
- 记一次 splice 导致 io.Copy 阻塞的排查过程
记一次 splice 导致 io.Copy 阻塞的排查过程 简而言之,net.TCPConn 的 ReadFrom 零拷贝实现 splice 在 1.21.0 - 1.21.4 删除了 SPLICE_ ...