惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
博客园 - 聂微东
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
Apple Machine Learning Research
Apple Machine Learning Research
阮一峰的网络日志
阮一峰的网络日志
大猫的无限游戏
大猫的无限游戏
GbyAI
GbyAI
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
The GitHub Blog
The GitHub Blog
博客园_首页
博客园 - 叶小钗
腾讯CDC
G
Google Developers Blog
Blog — PlanetScale
Blog — PlanetScale
宝玉的分享
宝玉的分享
D
Docker

博客园 - Grandyang

[LeetCode] 1374. Generate a String With Characters That Have Odd Counts 生成每种字符都是奇数个的字符串 [LeetCode] 1373. Maximum Sum BST in Binary Tree 二叉搜索子树的最大键值和 [LeetCode] 1372. Longest ZigZag Path in a Binary Tree 二叉树中的最长交错路径 [LeetCode] 1371. Find the Longest Substring Containing Vowels in Even Counts 每个元音包含偶数次的最长子字符串 [LeetCode] 1370. Increasing Decreasing String 上升下降字符串 [LeetCode] 1368. Minimum Cost to Make at Least One Valid Path in a Grid 使网格图至少有一条有效路径的最小代价 [LeetCode] 1367. Linked List in Binary Tree 二叉树中的链表 [LeetCode] 1366. Rank Teams by Votes 通过投票对团队排名 [LeetCode] 1365. How Many Numbers Are Smaller Than the Current Number 有多少小于当前数字的数字 [LeetCode] 1363. Largest Multiple of Three 形成三的最大倍数 [LeetCode] 1362. Closest Divisors 最接近的因数 [LeetCode] 1361. Validate Binary Tree Nodes 验证二叉树 [LeetCode] 1360. Number of Days Between Two Dates 日期之间隔几天 [LeetCode] 1359. Count All Valid Pickup and Delivery Options 有效的快递序列数目 [LeetCode] 1358. Number of Substrings Containing All Three Characters 包含所有三种字符的子字符串数目 [LeetCode] 1357. Apply Discount Every n Orders 每隔n个顾客打折 [LeetCode] 1356. Sort Integers by The Number of 1 Bits 根据数字二进制下1 的数目排序 [LeetCode] 1354. Construct Target Array With Multiple Sums 多次求和构造目标数组 [LeetCode] 1353. Maximum Number of Events That Can Be Attended 最多可以参加的会议数目 [LeetCode] 1352. Product of the Last K Numbers 最后 K 个数的乘积 [LeetCode] 1351. Count Negative Numbers in a Sorted Matrix 统计有序矩阵中的负数 [LeetCode] 1349. Maximum Students Taking Exam 参加考试的最大学生数
[LeetCode] 1375. Number of Times Binary String Is Prefix-...
Grandyang · 2026-08-29 · via 博客园 - Grandyang

You have a 1-indexed binary string of length n where all the bits are 0 initially. We will flip all the bits of this binary string (i.e., change them from 0 to 1) one by one. You are given a 1-indexed integer array flips where flips[i] indicates that the bit at index flips[i] will be flipped in the ith step.

A binary string is prefix-aligned if, after the ith step, all the bits in the inclusive range [1, i] are ones and all the other bits are zeros.

Return the number of times the binary string is prefix-aligned during the flipping process.

Example 1:

Input: flips = [3,2,4,1,5]
Output: 2
Explanation: The binary string is initially "00000".
After applying step 1: The string becomes "00100", which is not prefix-aligned.
After applying step 2: The string becomes "01100", which is not prefix-aligned.
After applying step 3: The string becomes "01110", which is not prefix-aligned.
After applying step 4: The string becomes "11110", which is prefix-aligned.
After applying step 5: The string becomes "11111", which is prefix-aligned.
We can see that the string was prefix-aligned 2 times, so we return 2.

Example 2:

Input: flips = [4,1,2,3]
Output: 1
Explanation: The binary string is initially "0000".
After applying step 1: The string becomes "0001", which is not prefix-aligned.
After applying step 2: The string becomes "1001", which is not prefix-aligned.
After applying step 3: The string becomes "1101", which is not prefix-aligned.
After applying step 4: The string becomes "1111", which is prefix-aligned.
We can see that the string was prefix-aligned 1 time, so we return 1.

Constraints:

  • n == flips.length
  • 1 <= n <= 5 * 10^4
  • flips is a permutation of the integers in the range [1, n].

这道题给了一个长度为n的二进制字符串,初始化均为 '0',然后又给了一个 flips 数组,每次翻转 flips[i] 位置的字符。然后定义了一个前缀一致的概念,即在第i步时,若范围 [1, i] 内的字符全是 '1',且其他位上均为 '0'。然后问在翻转的过程中,会出现前缀一致的次数。这道题博主最新想到的方式其实是位操作 Bit Operation,因为是需要翻转二进制的位,很自然的联想到用 “亦或” 操作,只要 “亦或“ 个1,就可以翻转位了。然后验证前缀一致也可以用右移操作来进行,这里我们不用字符串,而是用一个真实的二进制数,比如验证 11110 的话,就是验证前四位是否都是1,那么只要把 11110 右移1位,然后看是不是等于 2^4 - 1 就可以了。写完代码后,博主很有信心的 submit 了,结果发现会有 failed case,原来给的 test case 的n可能很大,远超整型数的 32 位,长整型的 64 位,后来定睛一看,题目中已经限定了n的范围是 [1, 50000],所以位操作的平移肯定不行,只得另辟蹊径。

既然位操作不行,那还是用字符串吧,就建立一个长度为n的字符串,然后按步骤进行翻转吧,也没什么难度。无非就是要验证字符串的前i个字符是否都为 ‘1’ 嘛,直接用 substr 来取字串就行了,然后判断是否都是 ‘1’ 即可。满心期待以为这次绝对过了,结果发现 Memory Limit Exceeded (MLE) 了,内存使用超标了。连新建长度为n的字符串都不允许,这是博主万万没想到的,那么这道题一定存在很 tricky 的解法,得好好分析一下。博主刚开始以为 flips 里的数组是任意数字,可能会出现重复数字,但是仔细看了下题目的限制条件,发现 flips 数组里面是 [1, n] 中的全排列,即不会有重复数字。这样的话,当前缀一致出现的时候,则范围内 [1, i] 内的数字都会出现,可能顺序不同,那么一个简单直接的判断方法就是求和,只要数字和跟 [1, i] 中的数字和相同,就一定是前缀一致。这里使用两个变量 sum 和 target,遍历 flips 数组,翻转第 flips[i-1] 个数字时候,把 flips[i-1] 加到 sum 中,把i加到 target 中,如果 sum 和 target 相等,则说明前缀一致了,res 自增1即可,参见代码如下:

解法一:

class Solution {
public:
    int numTimesAllBlue(vector<int>& flips) {
        int n = flips.size(), res = 0, sum = 0, target = 0;
        for (int i = 1; i <= n; ++i) {
            sum += flips[i - 1];
            target += i;
            if (sum == target) {
                ++res;
            }
        }
        return res;
    }
};

实际上我们并不需要计算数字之和,只需要统计需要翻转的位置中最大的值 curMax,如果这个最大值正好等于当前的遍历位置i,则说明前缀一致出现了,这也不难理解,因为当遍历到位置i时,说明此时总共翻转了i个数字,且每个翻转的位置中最大的数字就是i,则说明i位置之前的每个数字有且只出现了一次,即所有数字都翻转成1了,即前缀一致的情况,参见代码如下:

解法二:

class Solution {
public:
    int numTimesAllBlue(vector<int>& flips) {
        int n = flips.size(), res = 0, curMax = 0;
        for (int i = 1; i <= n; ++i) {
            curMax = max(curMax, flips[i - 1]);
            if (curMax == i) ++res;
        }
        return res;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1375

类似题目:

Bulb Switcher

Bulb Switcher II

参考资料:

https://leetcode.com/problems/number-of-times-binary-string-is-prefix-aligned

https://leetcode.com/problems/number-of-times-binary-string-is-prefix-aligned/solutions/532538/javacpython-straight-forward-o1-space-by-egzx/

LeetCode All in One 题目讲解汇总(持续更新中...)