[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 ...
随机推荐
- ADG备库中某个PDB缺失temp文件
之前认为缺失的temp文件在开库时会自动创建,但其实也有不能自动创建的场景,alert会有类似如下提示: 2023-05-11T20:35:35.974983+08:00 AWR(6):******* ...
- 小知识:RHEL7上设置Keepalived日志重定向
1.配置 /etc/sysconfig/keepalived 文件 2.添加keepalived日志保存位置的配置 3.修改 /lib/systemd/system/keepalived.servic ...
- Delphi TStringList 有趣的CommaText和DelimitedText
CommaText 在没有指定StrictDelimiter=true的情况下,当列表中项中 包含 空格和逗号的时候就默认的 在这个字符串上面 增加 双引号 很智能吧 例子1: var MyList: ...
- 点亮.NET的文字云艺术之光——Sdcb.WordCloud 2.0
点亮.NET的文字云艺术之光--Sdcb.WordCloud 2.0 作为一名.NET开发者,你是否渴望拥有一个强大且易用的库,用以在你的应用程序中创造美轮美奂的文字云?我在经过一轮农历新年前的码力全 ...
- NC204418 新集合
题目链接 题目 题目描述 集合 \(s\) 中有整数 \(1\) 到 \(n\) ,牛牛想从中挑几个整数组成一个新的集合. 现在牛妹给牛牛加了 \(m\) 个限制 ,每个限制包含两个整数 \(u\) ...
- NC50959 To the Max
题目链接 题目 题目描述 Given a two-dimensional array of positive and negative integers, a sub-rectangle is any ...
- [Android逆向] 重打包时报BrutException
执行apktool b --use-aapt2 进行重打包时,重打包失败,抛出异常 apktool b /Users/***/work/appsApk/testApp --use-aapt2 I: U ...
- 阿里云 SMS 短信 Java SDK 封装
Github & Issues: https://github.com/cn-src/aliyun-sms 官方文档:https://help.aliyun.com/document_deta ...
- 前后端分离解决跨域cors问题
修改windows的hosts文件 vim C:\Windows\System32\drivers\etc\hosts 添加域名 前端:www.luffycity.cn 后端:api.luffycit ...
- 有了这份Java面试中的葵花宝典,让你面试起飞!!!
HashMap面试题 HashMap与HashTable的区别 1.HashMap线程不安全 HashTable 线程是安全的采用synchronized 2.HashMap允许存放key 为null ...