方法一:朴素模拟法——king补充空位
public class Solution { public boolean IsContinuous(int [] numbers) { int[] count = new int[14];//0~13,普通牌卡槽 int kingCount = 0; for(int i=0; i<=4; ++i){ if(numbers[i] == 0){ ++kingCount; } else{ if(count[numbers[i]] == 1)return false;//有重复,直接false,不可能同花顺了 count[numbers[i]] = 1; } } int num =0;//连续个数 for(int i=1; i<=13; ++i){//遍历count[]数组 if(count[i] == 1) ++num; else if(num!=0 || num<i-8){//补位:普通补位+末尾补位(i>=9 && num<i-8时,即使末尾没有牌,也要提前用king的情况) if(kingCount == 0)return false; else{ --kingCount; ++num; } } if(num == 5)return true;//及时 } return false; } }//时间O(1) 空间O(1) //这题由于输入的规模是固定的,所以复杂度全部是O(1) //但性能上还是有差异:方法二略优于方法一
方法二:利用特性——普通卡不重复时,max-min<=4即可
public class Solution { public boolean IsContinuous(int [] numbers) { int count[] = new int[14];//正好对应0-13的卡牌(卡牌号->次数) int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE;//把min设置为最大,max设置最小 for(int i=0; i<5; ++i){ if(numbers[i]!=0){//0不参加 if(++count[numbers[i]] > 1)return false;//保证普通牌无重复 if(numbers[i] > max) max=numbers[i]; if(numbers[i] < min) min=numbers[i]; } } return (max-min<=4) ? true : false;//注意三元运算符的写法(三元运算符返回的是两个值二选一) } }//时间O(1) 空间O(1)
查重:上面是用数组,下面是用Set
import java.util.HashSet; public class Solution { public boolean IsContinuous(int [] numbers) { HashSet<Integer> set = new HashSet<Integer>();//HashSet int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for(int i=0; i<5; ++i){ if(numbers[i]!=0){ if(!set.add(numbers[i]))return false;//HashSet if(numbers[i] > max) max=numbers[i]; if(numbers[i] < min) min=numbers[i]; } } return (max-min<=4) ? true : false; } }//时间O(1) 空间O(1)