philosyang.com

2222. Number of Ways to Select Buildings | 1657

wrong interpretation & wrong result:

 1class Solution:
 2    def numberOfWays(self, s: str) -> int:
 3        # either 0101... or 1010...
 4        # if 0, find how many 1s until another 0
 5        # if 1, find how many 0s until another 1
 6        # [count(continuous 0 or 1s), count(continuous 0 or 1s), ...]
 7        # "001101" -> [2,2,1,1]
 8        # 2*2*1 + 2*1*1 = 6
 9        # can go with a length == 3 running product, result += each time
10
11        if not s:
12            return 0
13
14        consecutive = []
15        prev = s[0]
16        combo = 0
17
18        for c in s:
19            if c == prev:
20                combo += 1
21            else:
22                consecutive.append(combo)
23                prev = c
24                combo = 1
25
26        consecutive.append(combo)
27
28        # print(consecutive)
29
30        if len(consecutive) < 3:
31            return 0
32
33        n = len(consecutive)
34        running_product = consecutive[0] * consecutive[1] * consecutive[2]
35        result = running_product
36        # print(result, running_product)
37
38        for i in range(3, n):
39            running_product *= consecutive[i]
40            running_product = running_product // consecutive[i - 3]
41            result += running_product
42            # print(result, running_product)
43
44        return result

thinking in another perspective - prefix sum - works:

 1class Solution:
 2    def numberOfWays(self, s: str) -> int:
 3        # we focus on the second building.
 4        # for each char
 5        # if 0, then the possibilities of involving this 0 as the second building is
 6        # (number of 1s before this 0) * 1 * (number of 1s after this 0)
 7
 8        n = len(s)
 9        num_zeros = s.count("0")
10        num_ones = n - num_zeros
11        zeros_to_the_left = ones_to_the_left = result = 0
12
13        for c in s:
14            if c == "0":
15                result += ones_to_the_left * (num_ones - ones_to_the_left)
16                zeros_to_the_left += 1
17            else:  # c == "1"
18                result += zeros_to_the_left * (num_zeros - zeros_to_the_left)
19                ones_to_the_left += 1
20
21        return result

takeaways:

  1. brought prefix sum out of my toolbox so that I know I have this tool

#String #Prefix-Sum #Python