@@ -74,11 +74,13 @@ tags:
7474
7575<!-- solution:start -->
7676
77- ### 方法一:统计 010 和 101 的出现次数
77+ ### 方法一:计数 + 枚举
7878
79- 有效方案只有两种情况:$010$ 和 $101$。枚举中间数字,累计方案数 。
79+ 根据题目描述,我们需要选择 $3$ 栋建筑,且相邻的两栋不能是同一类型 。
8080
81- 时间复杂度 $O(n)$,其中 $n$ 表示 $s$ 的长度。
81+ 我们可以枚举中间的建筑,假设为 $x$,那么左右两边的建筑类型只能是 $x \oplus 1$,其中 $\oplus$ 表示异或运算。因此,我们可以使用两个数组 $l$ 和 $r$ 分别记录左右两边的建筑类型的数量,然后枚举中间的建筑,计算答案即可。
82+
83+ 时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(1)$。
8284
8385<!-- tabs:start -->
8486
@@ -87,18 +89,13 @@ tags:
8789``` python
8890class Solution :
8991 def numberOfWays (self , s : str ) -> int :
90- n = len (s)
91- cnt0 = s.count(" 0" )
92- cnt1 = n - cnt0
93- c0 = c1 = 0
92+ l = [0 , 0 ]
93+ r = [s.count(" 0" ), s.count(" 1" )]
9494 ans = 0
95- for c in s:
96- if c == " 0" :
97- ans += c1 * (cnt1 - c1)
98- c0 += 1
99- else :
100- ans += c0 * (cnt0 - c0)
101- c1 += 1
95+ for x in map (int , s):
96+ r[x] -= 1
97+ ans += l[x ^ 1 ] * r[x ^ 1 ]
98+ l[x] += 1
10299 return ans
103100```
104101
@@ -108,23 +105,17 @@ class Solution:
108105class Solution {
109106 public long numberOfWays (String s ) {
110107 int n = s. length();
111- int cnt0 = 0 ;
112- for (char c : s. toCharArray()) {
113- if (c == ' 0' ) {
114- ++ cnt0;
115- }
108+ int [] l = new int [2 ];
109+ int [] r = new int [2 ];
110+ for (int i = 0 ; i < n; ++ i) {
111+ r[s. charAt(i) - ' 0' ]++ ;
116112 }
117- int cnt1 = n - cnt0;
118113 long ans = 0 ;
119- int c0 = 0 , c1 = 0 ;
120- for (char c : s. toCharArray()) {
121- if (c == ' 0' ) {
122- ans += c1 * (cnt1 - c1);
123- ++ c0;
124- } else {
125- ans += c0 * (cnt0 - c0);
126- ++ c1;
127- }
114+ for (int i = 0 ; i < n; ++ i) {
115+ int x = s. charAt(i) - ' 0' ;
116+ r[x]-- ;
117+ ans += 1L * l[x ^ 1 ] * r[x ^ 1 ];
118+ l[x]++ ;
128119 }
129120 return ans;
130121 }
@@ -138,19 +129,16 @@ class Solution {
138129public:
139130 long long numberOfWays(string s) {
140131 int n = s.size();
141- int cnt0 = 0 ;
142- for (char& c : s) cnt0 += c == '0' ;
143- int cnt1 = n - cnt0 ;
144- int c0 = 0, c1 = 0 ;
132+ int l [ 2 ] {} ;
133+ int r [ 2 ] {} ;
134+ r [ 0 ] = ranges::count(s, '0') ;
135+ r [ 1 ] = n - r [ 0 ] ;
145136 long long ans = 0;
146- for (char& c : s) {
147- if (c == '0') {
148- ans += c1 * (cnt1 - c1);
149- ++c0;
150- } else {
151- ans += c0 * (cnt0 - c0);
152- ++c1;
153- }
137+ for (int i = 0; i < n; ++i) {
138+ int x = s[ i] - '0';
139+ r[ x] --;
140+ ans += 1LL * l[ x ^ 1] * r[ x ^ 1] ;
141+ l[ x] ++;
154142 }
155143 return ans;
156144 }
@@ -160,22 +148,38 @@ public:
160148#### Go
161149
162150```go
163- func numberOfWays(s string) int64 {
151+ func numberOfWays(s string) (ans int64) {
164152 n := len(s)
165- cnt0 := strings.Count(s, "0")
166- cnt1 := n - cnt0
167- c0, c1 := 0, 0
168- ans := 0
153+ l := [2]int{}
154+ r := [2]int{}
155+ r[0] = strings.Count(s, "0")
156+ r[1] = n - r[0]
169157 for _, c := range s {
170- if c == '0' {
171- ans += c1 * (cnt1 - c1)
172- c0++
173- } else {
174- ans += c0 * (cnt0 - c0)
175- c1++
176- }
158+ x := int(c - '0')
159+ r[x]--
160+ ans += int64(l[x^1] * r[x^1])
161+ l[x]++
177162 }
178- return int64(ans)
163+ return
164+ }
165+ ```
166+
167+ #### TypeScript
168+
169+ ``` ts
170+ function numberOfWays(s : string ): number {
171+ const n = s .length ;
172+ const l: number [] = [0 , 0 ];
173+ const r: number [] = [s .split (' ' ).filter (c => c === ' 0' ).length , 0 ];
174+ r [1 ] = n - r [0 ];
175+ let ans: number = 0 ;
176+ for (const c of s ) {
177+ const x = c === ' 0' ? 0 : 1 ;
178+ r [x ]-- ;
179+ ans += l [x ^ 1 ] * r [x ^ 1 ];
180+ l [x ]++ ;
181+ }
182+ return ans ;
179183}
180184```
181185
0 commit comments