[英]Find total possible ways to generate from given string
我有一個由 0 和 1 組成的二進制字符串。 現在我想要 select 一個長度為 3 的字符串,這樣沒有連續的字符是相同的。
例子:
Input : 01011010
Output: 20
解釋:所有可能的組合是:
[0, 1, 0]:: indices : 0,1,2 :: valid
[0, 1, 1]:: indices : 0,1,3
[0, 1, 1]:: indices : 0,1,4
[0, 1, 0]:: indices : 0,1,5 :: valid
[0, 1, 1]:: indices : 0,1,6
[0, 1, 0]:: indices : 0,1,7 :: valid
[0, 0, 1]:: indices : 0,2,3
[0, 0, 1]:: indices : 0,2,4
[0, 0, 0]:: indices : 0,2,5
[0, 0, 1]:: indices : 0,2,6
[0, 0, 0]:: indices : 0,2,7
[0, 1, 1]:: indices : 0,3,4
[0, 1, 0]:: indices : 0,3,5 :: valid
[0, 1, 1]:: indices : 0,3,6
[0, 1, 0]:: indices : 0,3,7 :: valid
[0, 1, 0]:: indices : 0,4,5 :: valid
[0, 1, 1]:: indices : 0,4,6
[0, 1, 0]:: indices : 0,4,7 :: valid
[0, 0, 1]:: indices : 0,5,6
[0, 0, 0]:: indices : 0,5,7
[0, 1, 0]:: indices : 0,6,7 :: valid
[1, 0, 1]:: indices : 1,2,3 :: valid
[1, 0, 1]:: indices : 1,2,4 :: valid
[1, 0, 0]:: indices : 1,2,5
[1, 0, 1]:: indices : 1,2,6 :: valid
[1, 0, 0]:: indices : 1,2,7
[1, 1, 1]:: indices : 1,3,4
[1, 1, 0]:: indices : 1,3,5
[1, 1, 1]:: indices : 1,3,6
[1, 1, 0]:: indices : 1,3,7
[1, 1, 0]:: indices : 1,4,5
[1, 1, 1]:: indices : 1,4,6
[1, 1, 0]:: indices : 1,4,7
[1, 0, 1]:: indices : 1,5,6 :: valid
[1, 0, 0]:: indices : 1,5,7
[1, 1, 0]:: indices : 1,6,7
[0, 1, 1]:: indices : 2,3,4
[0, 1, 0]:: indices : 2,3,5 :: valid
[0, 1, 1]:: indices : 2,3,6
[0, 1, 0]:: indices : 2,3,7 :: valid
[0, 1, 0]:: indices : 2,4,5 :: valid
[0, 1, 1]:: indices : 2,4,6
[0, 1, 0]:: indices : 2,4,7 :: valid
[0, 0, 1]:: indices : 2,5,6
[0, 0, 0]:: indices : 2,5,7
[0, 1, 0]:: indices : 2,6,7 :: valid
[1, 1, 0]:: indices : 3,4,5
[1, 1, 1]:: indices : 3,4,6
[1, 1, 0]:: indices : 3,4,7
[1, 0, 1]:: indices : 3,5,6 :: valid
[1, 0, 0]:: indices : 3,5,7
[1, 1, 0]:: indices : 3,6,7
[1, 0, 1]:: indices : 4,5,6 :: valid
[1, 0, 0]:: indices : 4,5,7
[1, 1, 0]:: indices : 4,6,7
[0, 1, 0]:: indices : 5,6,7 :: valid
在這些組合中只有 20 個組合是有效的,所以 output 是 20。
這是我的程序。
public static long process(String s) {
long result = 0;
int n = s.length();
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (s.charAt(i) == s.charAt(j)) {
continue;
}
for (int k = j + 1; k < n; k++) {
if (s.charAt(j) != s.charAt(k)) {
result++;
}
}
}
}
return result;
}
約束:
length of input is 1 to 2*10^5.
如何降低這個程序的時間復雜度。
讓我們首先看一下所有可能的長度為 3 的二進制字符串,使得沒有連續的字符相同:
101
010
考慮到這一點,問題可以重新表述為:
for each 0 in input, find all combinations of 1 on either side, plus
for each 1 in input, find all combinations of 0 on either side
對於任何給定的0
,任一側1
的組合數等於左側1
的數量乘以右側1
的數量(反之亦然)。
最后,我們可以根據當前字符在兩種情況之間切換,將這兩個for
循環合二為一。 我們還應該跟蹤左右兩側的0
和1
,因為我們不想一直重新計算它們。 這給我留下了以下算法:
var leftZeroes = 0
var leftOnes = 0
var rightZeroes = input.count { it == '0' }
var rightOnes = input.count { it == '1' }
var output = 0
for (char in input) {
if (char == '0') {
output += leftOnes * rightOnes
leftZeroes++
rightZeroes--
} else {
output += leftZeroes * rightZeroes
leftOnes++
rightOnes--
}
}
return output
時間復雜度: O(n)
( count
和for
在輸入大小上是線性的,其他一切都是常量)
額外的空間復雜度為O(1)
,因為任何時候都只存儲這五個整數
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.