【回文 字符串】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的数量为 str1...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;
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
员工说:技术至上,老板不信;投资人的代表说:技术至上,老板会信。
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法 用**C++**实现。

相关推荐
liulilittle12 分钟前
拥塞控制:排水终止的两种决策:OR 与 AND
网络·tcp/ip·计算机网络·算法·信息与通信·tcp·通信
weixin_307779131 小时前
从脚本执行到智能体协作:AI辅助测试能力的范式重构
运维·开发语言·人工智能·算法·测试用例
量化君也1 小时前
从回测到全自动实盘交易,全天候策略需要经历哪些改造?
大数据·人工智能·python·算法·金融
代码中介商1 小时前
C++ 智能指针完全指南(三):weak_ptr 与循环引用
开发语言·c++
fox_lht1 小时前
第十五章 函数式语言:迭代器和闭包
开发语言·后端·学习·算法·rust
BestOrNothing_20151 小时前
ROS2 C++ 小车控制完整实战(二):自定义 msg 消息发布与订阅保姆级教程
c++·ros2·subscriber·publisher·msg·topic通信·自定义接口
-森屿安年-2 小时前
91. 解码方法
c++·动态规划
有点。2 小时前
C++(二分答案)
c++
程序喵大人2 小时前
【C++并发系列】第一章:多线程读写同一个变量为什么会出错
开发语言·c++·多线程·并发
zhengzhouliuhaha2 小时前
智能医疗设备控费系统:以全院一体化管控,筑牢医疗资源“安全阀”
大数据·数据结构·人工智能·算法·安全·机器学习·软件需求