扑克牌可以组成顺子,大\小 王可以看成任何数字,并且A
看作1
,J
为11
,Q
为12
,K
为13
。5
张牌【A,0,3,0,5】
就可以变成“1,2,3,4,5
”(大小王分别看作2
和4
),这样就组成了顺子。(可以认为大小王是0
。)
输入五张牌,如果牌能组成顺子就输出true,否则就输出false
。
示例1
输入
[0,3,2,6,4]
返回值
true
第一种思路,先排序,0肯定是靠左边,然后统计0的个数,后面的数,按照第一个非0的数进行递增,如果不是递增,则需要使用0
牌补充,如果0
牌不够,需要放回false
,否则知道遍历完数组,返回true
。
public boolean IsContinuous(int[] numbers) {
// 数组长度不符合直接返回
if (numbers == null || numbers.length < 5) {
return false;
}
// 先排序
Arrays.sort(numbers);
// 统计0的个数
int numOfZero = 0;
// 初始化索引
int start;
// 统计0的个数
for (start = 0; start < numbers.length; start++) {
if (numbers[start] == 0) {
numOfZero++;
} else {
// 非0的时候跳出
break;
}
}
// 暂存0的个数
int n = numOfZero;
// 当前的数值
int cur = numbers[numOfZero];
// 从0的下两个位置开始
for (start++; start < numbers.length; ) {
// 如果可变的牌数量为0
if (numOfZero == 0) {
// 和前面的一个对比
if (numbers[start] != cur + 1) {
// 不等于当前数值+1的话,直接返回false
return false;
} else {
// 当前数值+1
cur++;
}
} else {
// 不等于当前数值+1的话,直接返回false
if (numbers[start] != cur + 1) {
// 可变牌数量-1
numOfZero--;
//当前值+1
cur++;
// 遍历下一张牌
continue;
} else {
// 相等则直接将当前值+1
cur++;
}
}
// 索引滑动到下一张牌
start++;
}
return true;
}
C++
代码如下:
class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
// 数组长度不符合直接返回
if (numbers.size() < 5) {
return false;
}
// 先排序
sort(numbers.begin(), numbers.end());
// 统计0的个数
int numOfZero = 0;
// 初始化索引
int start;
// 统计0的个数
for (start = 0; start < numbers.size(); start++) {
if (numbers[start] == 0) {
numOfZero++;
} else {
// 非0的时候跳出
break;
}
}
// 暂存0的个数
int n = numOfZero;
// 当前的数值
int cur = numbers[numOfZero];
// 从0的下两个位置开始
for (start++; start < numbers.size(); ) {
// 如果可变的牌数量为0
if (numOfZero == 0) {
// 和前面的一个对比
if (numbers[start] != cur + 1) {
// 不等于当前数值+1的话,直接返回false
return false;
} else {
// 当前数值+1
cur++;
}
} else {
// 不等于当前数值+1的话,直接返回false
if (numbers[start] != cur + 1) {
// 可变牌数量-1
numOfZero--;
//当前值+1
cur++;
// 遍历下一张牌
continue;
} else {
// 相等则直接将当前值+1
cur++;
}
}
// 索引滑动到下一张牌
start++;
}
return true;
}
};
另外一种做法,初始化一个最小牌14
,最大牌0
,直接使用set
保存数组的元素,如果set
中已经存在该元素,那么我们直接放回false
,如果set
中不存在该元素,则将该元素放进set
中,判断该元素是否小于最小牌,小于则更新最小牌,判断该元素是否大于最大牌,如果大于最大牌,则更新当前最大牌。
import java.util.HashSet;
public class Solution45 {
public boolean IsContinuous(int [] numbers) {
if(numbers==null||numbers.length<5){
return false;
}
HashSet<Integer>set = new HashSet<>();
int min = 14;
int max = 0;
for(int i=0;i<numbers.length;i++){
if(numbers[i]!=0){
if(set.contains(numbers[i])){
return false;
}
set.add(numbers[i]);
max= Math.max(max,numbers[i]);
min = Math.min(min,numbers[i]);
}
}
return max-min<5;
}
}
C++
代码如下:
class Solution {
public:
bool IsContinuous(vector<int> numbers) {
if (numbers.size() < 5) {
return false;
}
set<int> set;
int minValue = 14;
int maxValue = 0;
for (int i = 0; i < numbers.size(); i++) {
if (numbers[i] != 0) {
if (set.count(numbers[i]) > 0) {
return false;
}
set.insert(numbers[i]);
maxValue = max(maxValue, numbers[i]);
minValue = min(minValue, numbers[i]);
}
}
return maxValue - minValue < 5;
}
};
借助了set
,空间为5
,空间复杂度是常数,可以认为是O(1)
,时间复杂度也是O(1)
。