题目描述
有两种特殊字符:
第一种字符可以用一个比特 0
来表示
第二种字符可以用两个比特(10
或 11
)来表示、
给定一个以 0
结尾的二进制数组 bits
,如果最后一个字符必须是一位字符,则返回 true
。
示例1
输入: bits = [1, 0, 0]
输出: true
解释: 唯一的编码方式是一个两比特字符和一个一比特字符。
所以最后一个字符是一比特字符。
示例2
输入: bits = [1, 1, 1, 0]
输出: false
解释: 唯一的编码方式是两比特字符和两比特字符。
所以最后一个字符不是一比特字符。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/1-bit-and-2-bit-characters
题解思路
首先,从题目中能观测到的边界条件有两个:
(1)如果最后一个元素是1,说明最后一个字符一定是2比特字符
,直接返回false。
(2)如果长度为1,(只有一个元素 0),说明最后一个字符一定是1比特字符
,直接返回ture。
本来我是想看看能不能仅利用最后的三到四个元素推测出最后一个元素是否是一比特字符。但思来想去发现不太行orz
……
于是这一题我选择使用正序遍历的思想,将数组遍历一遍。从数组的第一个元素开始遍历,此时元素值只有两种情况,第一种情况是元素为0,是一比特字符;第二种情况是元素为1,肯定是二比特字符。
第一种情况可以直接跳到下一个元素进行判断,而第二种情况可以直接忽略下一个元素,跳到下下个元素。
如果循环到达最后一个元素,发现它已经是数组末尾的最后一个元素,说明它一定是一个1比特字符
,直接返回true。
如果循环到达数组以外,指针没有指到最后一个元素,说明它一定是一个2比特字符
,直接跳出循环返回false。
C++实现(罗嗦版)
class Solution {
public:
bool isOneBitCharacter(vector<int>& bits) {
int len = bits.size();
// 数组最后一个元素是1,最后一个字符一定是2比特字符
if(bits[len - 1] == 1){
return false;
}
// 数组长度为1,最后一个字符一定是1比特字符
else if(len == 1){
return true;
}
int pos = 0;
// 从头开始遍历数组
while(pos < len){
// 1比特字符,直接跳到下一个元素进行判断
if(bits[pos] == 0){
++pos;
}
// 2比特字符,跳到下下个元素进行判断
else if(bits[pos] == 1){
pos += 2;
}
// 一定是一个1比特字符,返回true
if(pos == len - 1){
return true;
}
}
return false;
}
};
C++实现(简洁版)
然而我后面发现其实不需要限制边界条件,这样还可以简化代码量。
同时可以利用元素值进行指针跳跃长度的计算,这个时候就无需对元素值进行判断了。
class Solution {
public:
bool isOneBitCharacter(vector<int>& bits) {
int len = bits.size();
int pos = 0;
// 边界是len - 1,一旦 pos 到 len-1 或 len 的位置就直接跳出循环
while(pos < len - 1){
// 计算bits[pos] + 1得到指针跳跃长度
pos += bits[pos] + 1;
}
// pos 在 len-1 的位置说明最后一个字符是1比特字符
return pos == len - 1;
}
};