@@ -74,11 +74,13 @@ tags:
74
74
75
75
<!-- solution:start -->
76
76
77
- ### 方法一:统计 010 和 101 的出现次数
77
+ ### 方法一:计数 + 枚举
78
78
79
- 有效方案只有两种情况:$010$ 和 $101$。枚举中间数字,累计方案数 。
79
+ 根据题目描述,我们需要选择 $3$ 栋建筑,且相邻的两栋不能是同一类型 。
80
80
81
- 时间复杂度 $O(n)$,其中 $n$ 表示 $s$ 的长度。
81
+ 我们可以枚举中间的建筑,假设为 $x$,那么左右两边的建筑类型只能是 $x \oplus 1$,其中 $\oplus$ 表示异或运算。因此,我们可以使用两个数组 $l$ 和 $r$ 分别记录左右两边的建筑类型的数量,然后枚举中间的建筑,计算答案即可。
82
+
83
+ 时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。空间复杂度 $O(1)$。
82
84
83
85
<!-- tabs:start -->
84
86
@@ -87,18 +89,13 @@ tags:
87
89
``` python
88
90
class Solution :
89
91
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" )]
94
94
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
102
99
return ans
103
100
```
104
101
@@ -108,23 +105,17 @@ class Solution:
108
105
class Solution {
109
106
public long numberOfWays (String s ) {
110
107
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' ]++ ;
116
112
}
117
- int cnt1 = n - cnt0;
118
113
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]++ ;
128
119
}
129
120
return ans;
130
121
}
@@ -138,19 +129,16 @@ class Solution {
138
129
public:
139
130
long long numberOfWays(string s) {
140
131
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 ] ;
145
136
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] ++;
154
142
}
155
143
return ans;
156
144
}
@@ -160,22 +148,38 @@ public:
160
148
#### Go
161
149
162
150
```go
163
- func numberOfWays(s string) int64 {
151
+ func numberOfWays(s string) (ans int64) {
164
152
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]
169
157
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]++
177
162
}
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 ;
179
183
}
180
184
```
181
185
0 commit comments