【回文 字符串】3677 统计二进制回文数字的数目|2223

本文涉及知识点

回文 字符串

3677 统计二进制回文数字的数目

给你一个 非负 整数 n。

如果一个 非负 整数的二进制表示(不含前导零)正着读和倒着读都一样,则称该数为 二进制回文数。

返回满足 0 <= k <= n 且 k 的二进制表示是回文数的整数 k 的数量。

注意: 数字 0 被认为是二进制回文数,其表示为 "0"。

示例 1:

输入: n = 9

输出: 6

解释:

在范围 [0, 9] 内,二进制表示为回文数的整数 k 有:

0 → "0"

1 → "1"

3 → "11"

5 → "101"

7 → "111"

9 → "1001"

0, 9\] 中的所有其他值的二进制形式都不是回文。因此,计数为 6。 示例 2: 输入: n = 0 输出: 1 解释: 由于 "0" 是一个回文数,所以计数为 1。 提示: 0 \< = n \< = 10 15 0 \<= n \<= 10\^{15} 0\<=n\<=1015 ## 回文字 符串 令str是n的二进制字符串,str的长度是N。 所有长度N-1的二进制回文都符合题意。故只需考虑N位回文。 str2的右半部分长度rLen = N/2,leftLen= N - N/2。 枚举目标串的左半部分,因为是回文,左半部分确定后,右半部分也确定了。 str1是回文,str1和str长度相同,长度为leftLen的前缀相同,如果str1 ≤ \\le ≤str,则符合题意。 str2是回文, str2和str长度相同,str2长度为leftLen的前缀小于str长度为leftLen的前缀,则str2一定符合题意。 如果 l e f t L e n \> 1 leftLen \>1 leftLen\>1,则str2的数量为 str\[1...leftLen-1\]。**计算一** 。 如果 l e f t L e n = = 1 leftLen==1 leftLen==1 如果 N是1, str2的数量是 n。n是0符合计算1,n是1**不符合计算一** 。 如果N是2,则str2为0。符合计算一。 ### 计算n位回文 令n是偶数, n ≥ 2 n \\ge 2 n≥2。fullbit(n+1)=fullbit(n+2)= fullbit(n) × \\times × 2。 最中间的一位(两位)可以选择0或1。 ## 代码 ### 核心代码 ```cpp class Solution { public: int countBinaryPalindromes(long long n) { if (1 == n) { return 2; } string s = To2Str(n); const int N = s.length(); int ans = 0; for (int i = 0;i < N;i++) { ans += fullbit(i); } const int rLen = N / 2; const int leftLen = N - rLen; string rs = s; for (int i = 0;i < rLen;i++) { rs[N - 1 - i] = s[i]; } if (rs <= s) { ans++; }//左半部分和n相等 //左半部分小于n if (leftLen > 1) { int cur = 0; for (int i = 1;i < leftLen;i++) { cur = cur * 2 + (s[i] - '0'); } ans += cur; } return ans; } string To2Str(long long n) { if (0 == n) { return "0"; } string s; while (n) { s += (n & 1) ? "1" : "0"; n /= 2; } return string(s.rbegin(), s.rend()); } int fullbit(int n) { if (0 == n) { return 0; } if (1 == n) { return 2; } if (2 == n) { return 1; } return 1 << ((n - 1) / 2); } }; ``` ### 单元测试 ```cpp TEST_METHOD(TestMethod11) { auto res = Solution().countBinaryPalindromes(9); AssertEx(6, res); } TEST_METHOD(TestMethod12) { auto res = Solution().countBinaryPalindromes(0); AssertEx(1, res); } TEST_METHOD(TestMethod13) { int iAct = 0; for (long long n = 0; n < 10000;n++) { string s = Solution().To2Str(n); if (Is(s)) { iAct++; } auto res = Solution().countBinaryPalindromes(n); AssertEx(iAct, res); } } bool Is(string& s) { const int N = s.length(); for (int i = 0;i < N / 2;i++) { if (s[i] != s[N - 1 - i]) { return false; } } return true; } ``` ![](https://img-blog.csdnimg.cn/8d37dcd13ddb4df9af8f95fefd86828d.gif) ## 扩展阅读 | 我想对大家说的话 | |----------------------------------------------------------------------------------------------------------------------------------------------------------------| | 工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《[算法与数据汇总](https://blog.csdn.net/he_zhidan/article/details/137131684)》。 | | 学习算法:按章节学习《[喜缺全书算法册](https://download.csdn.net/download/he_zhidan/88348653)》,大量的题目和测试用例,[打包下载](https://blog.csdn.net/he_zhidan/article/details/140733677)。重视操作 | | 有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 | | 员工说:技术至上,老板不信;投资人的代表说:技术至上,老板会信。 | | 闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 | | 子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 | | 如果程序是一条龙,那算法就是他的是睛 | | 失败+反思=成功 成功+反思=成功 | ### 视频课程 先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。 如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程 ### 测试环境 操作系统:win7 开发环境: VS2019 **C++17** 或者 操作系统:win10 开发环境: VS2022 **C++17** 如无特殊说明,本**算法** 用\*\*C++\*\*实现。 ![](https://i-blog.csdnimg.cn/blog_migrate/4b48f80cdf99b7ea9bda88ceb91d788f.gif)

相关推荐
李余博睿(新疆)4 小时前
c++分治算法
c++
Tisfy4 小时前
LeetCode 0085.最大矩形:单调栈
算法·leetcode·题解·单调栈
oioihoii4 小时前
Protocol Buffers 编码原理深度解析
c++
消失的旧时光-19434 小时前
函数指针 + 结构体 = C 语言的“对象模型”?——从 C 到 C++ / Java 的本质统一
linux·c语言·开发语言·c++·c
mit6.8244 小时前
出入度|bfs|状压dp
算法
hweiyu004 小时前
强连通分量算法:Kosaraju算法
算法·深度优先
源代码•宸4 小时前
Golang语法进阶(定时器)
开发语言·经验分享·后端·算法·golang·timer·ticker
郝学胜-神的一滴4 小时前
Linux系统编程:深入理解读写锁的原理与应用
linux·服务器·开发语言·c++·程序人生
Larry_Yanan4 小时前
Qt多进程(十一)Linux下socket通信
linux·开发语言·c++·qt