判断是否为连续的数字,需要额外考虑的情况有一个,就是 0 可以代表任何数字,并且最多出现两次
给出的长度为 5 的数组不一定是顺序
bool isStraight(vector<int>& nums) {
sort(nums.begin(), nums.end());
// 没有 0 的情况
if (nums[0] == 0) {
// 只有一个 0 的情况
if (nums[1] == 0) {
}
else {
// 有两个 0 的情况,必定是从 0 开始?不一定
}
}
else {
// 没有 0 的情况
}
}
分类讨论的想法很快就被否决了,我想到了《剑指Offer》前面的数组题目中涉及到的,利用数组下标,因为很明显,数组下标也是一个连续的数列,可以用于建立一个映射关系
判断连续,一个一个确认,但是很明显由于 0 的特殊存在和规则,从小往大数并不合理,那么就从大往小数,最大的数字一定是确定的!
那么数的过程中出现了对不上的数字怎么办呢?用 0 补,如果有的话,那我怎么知道有没有呢?用一个指针从最左边开始向右移动,排序后的 0 (如果存在)一定在最左边!
那么这道题目的解题思路就出来了,双指针:
head1 头指针初始位置指向最左(最小的)数,head2 尾指针指向最右(最大的)数
head2 从右向左移动,检查下一个数字是否比上一个数字小 1,如果不是,确认差了几个数字,然后去检查左指针指向是否为 0,是 0 就可以补一个向右移动一位表示用掉了(这里差如果大于 2 可以直接 false)
能够补上就继续走,走到两个指针相遇则为 true
不是 0,补不上则为 false
bool isStraight(vector<int>& nums) {
sort(nums.begin(), nums.end());
int point1 = 0, point2 = 3, diff;
while (point2 != point1) {
diff = nums[point2] - nums[point2 + 1];
if (diff > 3) return false;
while (diff > 1) {
if (nums[point1] == 0) {
point1++;
diff--;
}
else return false;
}
point2--;
}
return true;
}
死在[0,0,2,2,5]
- 没有考虑到元素重复的情况
- 差值相减写反了
- 最外层while循环退出条件也不对
- 若干副牌,不止两张王,那么最极端的情况就是 5 个 0
第一份 AC 代码
bool isStraight(vector<int>& nums) {
sort(nums.begin(), nums.end());
int point1 = 0, point2 = 3, diff;
if (nums[point2] == 0) return true;
while (point2 >= point1) {
if (nums[point2]==0) break;
diff = nums[point2+1] - nums[point2];
if (diff > 4 || diff == 0) return false;
while (diff > 1) {
if (nums[point1] == 0) {
point1++;
diff--;
}
else return false;
}
point2--;
}
return true;
}
但是这样内存占用率太高
bool isStraight(vector<int>& nums) {
sort(nums.begin(), nums.end());
int point1 = 0, point2 = 3, diff;
while (point2 >= point1 && nums[point2] != 0) {
diff = nums[point2+1] - nums[point2];
if (diff > 4 || diff == 0) return false;
while (diff > 1) {
if (nums[point1] == 0) {
point1++;
diff--;
}
else return false;
}
point2--;
}
return true;
}
而且其实也没有用上下标,可能将过程和排序过程结合会更好
标签:point1,return,nums,Offer,61,point2,diff,false,顺子 From: https://www.cnblogs.com/yaocy/p/17615209.html