扑克牌中的顺子
https://leetcode.cn/problems/bu-ke-pai-zhong-de-shun-zi-lcof/description/
题目分析
一共放置5个朝代文物,题目要求判断文物所属朝代编号是否连续,元素里面含有多个0,也表示连续,除此之外,其他元素要求连续;
这个跟我们生活中玩牌一样,一共5张牌,有三种情况:
- 可以有大王/小王,或者大小王都有(对应元素0),并且大小王可以替换为任何元素,剩下的4张牌或3张牌要保证是顺子;
1.1 验证第一种情况,列表中只有一个大王/小王:
除去大O,剩下的4张牌如何算是连续的?
O,1,2,3,8 这个不算连续;
O,1,2,3,5 这个算连续;
O,1,2,3,6 这个不算连续;
我们可以找到规律,只要最大值和最小值之差<= 4 的情况下,可以算作连续;
左侧区域 | x1(min),x1+1,x1+2,x1+3,x1+4(max) | 右侧区域
对于上述第一种情况, 8 > x1+4(5),超出最大值范围,不满足
对于上述第二种情况,5 == x1+4(5), 大O 可以替换为x1+3,满足连续元素
对于上述第三种情况,6 > x1+4(5),超出最大值范围,不满足
1.2 验证第二种情况,列表中有大王和小王:
除去两个大O情况,剩下的3张牌如何算是连续?
我们可以类比1.1 中规律,只要剩下的3张牌最大值和最小值之差 <= 4 的情况下,可以算作连续;
例如:
O,O,1,2,5 算作连续,两个大O 可以替换为3,4
O,O,1,2,6 6 > x1min+4(5),不能算作连续
1.3 验证第三种情况,没有大小王情况下,x1,x2,x3,x4,x5 如何算是连续?
首选,这5个元素要保证不重复,最大值-最小值 <= 4;
例如:
2,1,3,4,5 符合上述条件,算是连续
2,2,1,3,4 元素有重复,不算连续
2,1,3,4,6 元素6 > x1min_4(5),超出范围,不能算连续
规律总结
经过上述三种情况分析,可以得出元素连续条件:
- 列表中元素O可以有多个 && 除去大O的情况下, max-min <= 4
- 列表中元素如果 != O && 元素不能重复 && 除去大O的情况下, max-min <= 4
编程实现
/**
0 可以重复放置多次
除了0之外不能有重复元素,最大值-最小值 < 4
*/
public boolean checkDynasty(int[] places) {
if(places == null || places.length <= 0){
return false;
}
Set<Integer> set = new HashSet();
int maxValue = 0;
int minValue = 0;
int i = 0;
while(i < places.length){
if(places[i] == 0){
i++;
}else{
if(set.contains(places[i])){
//存在重复元素
return false;
}else{
set.add(places[i]);
if(maxValue == 0 && minValue == 0){
maxValue = places[i];
minValue = places[i];
}
if(places[i] > maxValue){
maxValue = places[i];
}
if(places[i] < minValue){
minValue = places[i];
}
i++;
}
}
}
return maxValue - minValue < 5;
}