题目比较简单
cpp
class Solution {
public:
vector<bool> prefixesDivBy5(vector<int>& nums) {
vector<bool> answer; // 用vector存储结果(可安全返回)
// 为避免溢出,始终只维护余数(范围 0~4),不会出现大数溢出问题。
int remainder = 0; // 用于维护当前前缀对5的余数
for (int num : nums) {
// 计算当前前缀的余数: 前余数*2+当前位,再模5(对应二进制 "左移一位
// + 新增当前位" 的十进制计算)
remainder = (remainder * 2 + num) % 5;
// 判断余数是否为0,若为 0,说明当前前缀能被 5整除,结果加入true,否则加入false
answer.push_back(remainder == 0);
}
return answer;
}
};
什么是 "前缀"?
在一个序列中,"前缀" 指的是从序列开头到某个位置的所有元素组成的子序列。
例如,对于二进制序列 [1, 0, 1, 1]:
- 第 0 个元素的前缀是
[1] - 第 1 个元素的前缀是
[1, 0] - 第 2 个元素的前缀是
[1, 0, 1] - 第 3 个元素的前缀是
[1, 0, 1, 1]
什么是 "前缀余数"?
"前缀余数" 就是指上述每个 "前缀" 所代表的二进制数,转换为十进制后,对某个数(在本题中是 5)取余的结果。
例如,对于二进制序列 [1, 0, 1, 1] 和除数 5:
- 前缀
[1]代表的数是1,1 % 5 = 1,所以前缀余数是1。 - 前缀
[1, 0]代表的数是2,2 % 5 = 2,所以前缀余数是2。 - 前缀
[1, 0, 1]代表的数是5,5 % 5 = 0,所以前缀余数是0。 - 前缀
[1, 0, 1, 1]代表的数是11,11 % 5 = 1,所以前缀余数是1。
为什么 "前缀余数" 如此重要?
直接计算每个前缀的十进制数会有两个严重问题:
- 溢出 :当序列很长时(比如超过 30 位),其代表的十进制数会超出计算机中
int甚至long long类型的表示范围,导致计算错误。 - 低效:反复将长字符串或长序列转换为大数本身就是一个非常耗时的操作。
而 "前缀余数" 的计算则巧妙地解决了这两个问题,其核心在于利用了模运算的性质。