[英]1-bit and 2-bit Characters
我們有兩個特殊字符。 第一個字符可以用一位 0 表示。第二個字符可以用兩位(10 或 11)表示。
現在給定一個由幾個位表示的字符串。 返回最后一個字符是否必須是一位字符。 給定的字符串總是以零結尾。
示例 1:輸入:位 = [1, 0, 0] Output:真
輸入:位 = [1, 1, 1, 0] Output:假
class Solution {
public boolean isOneBitCharacter(int[] bits) {
int n = bits.length-1;
int count = 0;
for(int i=n;i<=n;i--){
if(bits[i]==1){
count++;
}else break;
}return count%2==0;
}
}
此代碼不適用於某些測試用例我的第二個示例測試用例不起作用
嘗試這個:
public boolean isOneBitCharacter(int[] bits) {
int n = bits.length - 1;
int count = 0;
while (count < n) {
count += bits[count] + 1;
}
return count == n;
}
解釋:
您從左到右開始閱讀,如果遇到bits[i] == 0
,則表示下一個字符將有 1 位。 如果bits[i] == 1
這意味着下一個字符將有 2 位。 您不斷將count
增加到每個下一個字符的開頭。 最后,如果count
等於n
,則意味着最后一個字符是 1 位。
對於長比特流,從最后調查比特流會快得多……但是檢測這些情況要困難得多。 當我們查看結尾位時:
.....00 // 1 bit
.....01 // error
.....10 // 1/2 bit
.....11 // 2 bit
我們可以立即確定答案,除非存在.....10
案例,在這種情況下我們需要再調查一點:
....110 // 1/2 bit
....010 // 2 bit
然后再次:
....1110 // 1/2 bit
....0110 // 1 bit
然后再次:
...11110 // 1/2 bit
...01110 // 2 bit
正如您所看到的,后續的計數確定最后一個字是 1 位還是 2 位(它是交替的),奇數計數是 1,偶數是 2 位字。
因此,只需檢測它是哪種情況並立即拋出答案或計算最后一個零之前的結果並從中確定答案。
這樣您就不需要處理整個 stream 直到遇到零。
所以:
.....11 // 2 bit or error
.....01 // error
.....00 // 1 bit
....010 // 2 bit
...0110 // 1 bit
..01110 // 2 bit
.011110 // 1 bit
0111110 // 2 bit
僅當您啟動 stream (開始時不為零)時才需要處理整個數組,但這是不可能的......因為它只是 stream 看起來像這樣的單一情況:
111.....111X
所以最后沒有或只有一個零,但最后一位之前的個數仍然會告訴你結尾是 1 位還是 2 位長......你可以這樣做:
last_word_bit_length= 1 + (consequent_ones_count&1)
我不在 JAVA 中編碼,所以這里是 C++ 示例(應該不難移植):
int last_word_bits(int *bits,int n)
{
int i=0;
if (n<1) return 0; // empty
if (n>=1) i|=bits[n-1];
if (n>=2) i|=bits[n-2]<<1;
if (i==1) return 0; // ...00 or ...0 -> error
if (i==0) return 1; // ...01 -> 1
if (i==3) return 2; // ...11 -> 2 or error
// count consequent ones
for (i=0,n-=2;n>=0;n--,i++)
if (bits[n]==0) break;
return 1+(i&1);
}
給出答案:
{1,0,0} -> 1
{1,1,1,0} -> 2
我期望比特流不包含錯誤,否則特殊情況i==3
也需要計算錯誤...以確定它是否是錯誤
考慮到循環的所有問題(在編輯之前和之后),很難說您實際嘗試了哪些代碼。
無論哪種方式,你的邏輯都是錯誤的。 您必須從左到右遍歷String
的“位”,並保留一些 state 變量來告訴您遇到的最后一個字符是 1 位還是 2 位字符。
例如:
boolean started2bit = false;
boolean last1bit = false;
for(int i=0;i<bits.length;i++) {
if (started2bit) { // previous bit was the start of a 2-bit character and current
// bit (either 1 or 0) ends that character
started2bit = false;
last1bit = false;
} else if (bits[i]==1) { // 1 starts a 2-bit character
started2bit = true;
last1bit = false;
} else { // current bit is 0, and it represents a 1-bit character
last1bit = true;
}
}
return last1bit; // the last character we read was a 1-bit character
或者,更簡單,正如漢斯建議的那樣:
boolean last1bit = false;
for(int i=0;i<bits.length;i++) {
if (bits[i]==1) { // 1 starts a 2-bit character
i++; // the next bit finishes a 2-bit character, so we can skip it
last1bit = false;
} else { // current bit is 0, and it represents a 1-bit character
last1bit = true;
}
}
return last1bit; // the last character we read was a 1-bit character
Python3 代碼基於上述@Spektre 的解決方案。 歡迎任何改進代碼的建議。
class Solution:
def isOneBitCharacter(self, bits: List[int]) -> bool:
# if it's only 1 bit
if len(bits) == 1:
if bits[0] == 0:
return True
else:
# throwInvalidInputException
return False
# if it ends in 1 then error
if bits[-1] == 1:
# throwInvalidInputException
return False
# if it ends in 00 then True
if bits[-2:] == [0, 0]:
return True
# if it ends in 10 then ??
if bits[-2:] == [1, 0]:
i = len(bits)
while i > 0:
i -= 1
if bits[i-1:i+1] == [0, 1]: break
# in case the loop completes - need to check the first character
if bits[i-1] == 1: i -= 1
# i is now pointing to the first 1 in ....11110
if len(bits[i:]) % 2 == 1:
return True
else:
return False
這將有助於理解“以 10 結尾”的情況:
"""
Assuming no invalid input is received.
F 10
F 010
T 110
F 0010
T 0110
F 1010
F 1110
111111110 - len odd True
11111110 - len even false
"""
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.