leetcode
leetcode 1401 ~ 1450
分割字符串的方案数

分割字符串的方案数

难度:

标签:

题目描述

代码结果

运行时间: 56 ms, 内存: 16.7 MB


/*
 * 使用 Java Stream 的解法:
 * 1. 计算总的 '1' 的数量。
 * 2. 如果不是 3 的倍数,返回 0。
 * 3. 通过流操作找到分割点并计算组合数。
 */

import java.util.stream.IntStream;

public class Solution {
    public int numWays(String s) {
        int MOD = 1000000007;
        int totalOnes = (int)s.chars().filter(c -> c == '1').count();
        if (totalOnes % 3 != 0) return 0;
        if (totalOnes == 0) return (int)(((long)(s.length() - 1) * (s.length() - 2) / 2) % MOD);

        int onesPerPart = totalOnes / 3;
        int[] counts = {0, 0, 0}; // {count, first, second}
        int onesSoFar = 0;

        for (char c : s.toCharArray()) {
            if (c == '1') onesSoFar++;
            if (onesSoFar == onesPerPart) counts[0]++;
            if (onesSoFar == onesPerPart + 1) counts[1]++;
            if (onesSoFar == 2 * onesPerPart) counts[2]++;
        }

        return (int)(((long)counts[1] * (long)counts[2]) % MOD);
    }
}

解释

方法:

首先,我们需要统计字符串中'1'的总数。如果'1'的总数不能被3整除,那么不可能等分成三个部分,直接返回0。如果没有'1',即字符串全为'0',则可以在任何两个'0'之间切割来形成三个部分,计算方式是组合数C(n-1, 2),其中n是字符串的长度。如果'1'的数量可以被3整除,我们计算每个部分应含有的'1'的数量,然后找到这些'1'在原字符串中的确切位置。具体地,我们需要计算第1/3和第2/3位置的'1'之间,以及第2/3和第3/3位置的'1'之间的'0'的数量,这些'0'可以灵活地分配到相邻的部分中。最后,将这两个间隔的长度相乘即可得到分割方案的总数。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在处理全为'0'的字符串时,为什么选择使用组合数C(n-1, 2)来计算分割方案数?
在全为'0'的字符串中,没有'1'来限制分割点的位置,因此任何两个位置都可以作为分割点来将字符串分为三部分。字符串长度为n时,我们需要选择两个位置来放置分割点,这些位置从字符串的第一个字符后到最后一个字符前的n-1个位置中选取。这是一个从n-1个元素中选择2个的组合问题,因此使用组合数公式C(n-1, 2)来计算分割方案的总数。
🦆
如何确保在统计字符串中'1'的总数时,不会漏掉任何一个'1',特别是当'1'紧挨着字符串边界时?
在Python代码中,通过遍历字符串的每个字符并检查它是否为'1',然后记录其索引,可以确保不会漏掉任何一个'1'。这种方法包括检查字符串的每个位置,无论'1'是否位于字符串的边界。因此,即使'1'位于字符串的开头或结尾,它们也会被正确地统计和记录。
🦆
如果'1'的数量可以被3整除,为什么计算两个分割点之间可以移动的'0'的数量是正确的方法?这样的计算对结果的准确性有什么影响?
如果'1'的数量可以被3整除,意味着可以将'1'平均分配到三个部分中。在这种情况下,关键是要确定每部分的'1'之间可以有多少个'0',因为这些'0'可以灵活地分配到相邻的部分中,从而形成不同的分割方案。计算两个分割点之间的'0'数量可以让我们知道每两个'1'集团之间有多少空间可以用来调整分割点的位置,从而影响到分割方案的总数。这种计算方法能够准确地反映分割点之间的灵活性,从而正确地计算出所有可能的分割方案。
🦆
在确定第1/3和第2/3位置的'1'之间的'0'数量时,实际上是如何处理边界条件,例如避免数组越界的?
在代码中,通过计算第1/3和第2/3位置的'1'的索引时,我们确保使用了正确的索引计算公式来避免数组越界。例如,使用`news[k // 3]`和`news[k // 3 - 1]`来找到第1/3位置的'1'的索引。这种方法确保在访问数组时索引是有效的,因为通过整数除法`k // 3`计算的结果总是在有效索引范围内。同时,由于'1'的数量已知可以被3整除,所以这些计算不会导致越界错误。

相关问题