LeetCode 659 Split Array into Consecutive Subsequences
思路
两遍循环
- 第一遍统计每个字的出现次数
- 第二遍判断当前字符是否可作为某个串的结尾,或一个新串的开头
比如[1, 2, 3, 3, 4, 5, 6]
,第二遍循环时,首先判断1可以作为开头,那么对2和第一个3的访问就可以忽略了,之后对第二个3可以作为一个开头,同样忽略4和5,对最后一个6,他可以作为以5结尾的串的后继,将其作为新结尾即可。
需要记录数字的可用个数,以及以上一个紧邻数字结尾
的串可用。
代码
class Solution {
public:
bool isPossible(vector<int> &nums) {
struct T {
int value, count;
int asEndCnt;
};
if (nums.size() < 3)
return false;
vector<T> values;
for (auto &&v : nums) {
if (values.empty() || values.back().value != v)
values.push_back(T{v, 1, 0});
else
values.back().count += 1;
}
if (values.size() < 3)
return false;
for (size_t i = 0; i < values.size(); i++) {
for (int j = 0; j < values[i].count; j++) {
if (i != 0 && values[i].value - values[i - 1].value == 1 && values[i - 1].asEndCnt > 0) {
values[i - 1].asEndCnt -= 1;
values[i].asEndCnt += 1;
} else if (i + 2 < values.size() &&
values[i + 1].count > 0 &&
values[i + 2].count > 0 &&
values[i + 1].value - values[i].value == 1 &&
values[i + 2].value - values[i + 1].value == 1) {
values[i + 1].count -= 1;
values[i + 2].count -= 1;
values[i + 2].asEndCnt += 1;
} else
return false;
}
}
return true;
}
};