扑克牌顺子:最直观的想法是,首先想想顺子的特点是什么。首先顺子中不能出现相同的元素,其次顺子中各元素相差值为1,如果相差值大于1,可以使用万能牌0进行补齐,同时要考虑元素之间相差值过大从而导致万能牌无法补齐的情况。具体做法如下:首先对数组进行排序,然后统计数组中0出现的次数,即可用的万能牌张数,接着遍历剩余非0元素,如果剩余元素出现相等情况,则直接返回false,即不能构成顺子,反之统计元素之间的差值,注意,此处的差值是大于正常差值1的差值,最后根据万能牌的张数与元素之间的差值比较来判断返回true还是false。
bool IsContinuous( vector<int> numbers ) { // 首先对numbers数组进行排序 sort(numbers.begin(),numbers.end()); // 统计数组中0出现的个数 int i=0; //i表示下标 int zero_num=0; //zero_num表示0的个数 while(numbers[i]==0) //i++放在循环条件中会导致数组异位 { zero_num++; i++; } // 遍历数组统计元素间隔 int interdiff=0; //interdiff表示元素间隔值 for(;(i+1)<numbers.size();i++) { // 如果出现相等元素则不能构成顺子 if(numbers[i+1]==numbers[i]) return false; // 正常的顺子元素两者之间间隔为1 其余则是补万能牌 interdiff+=(numbers[i+1]-numbers[i]-1); } // 如果功能牌可以补齐差值则返回true反之为false return zero_num>=interdiff?true:false; }
idea:既然不能出现重复元素,那么可以使用集合uset来进行处理。具体做法如下:遍历数组,如果遇到0则直接跳过,反之查找uset中是否包含该元素,如果包含则表明出现了重复元素,直接返回false,反之将该元素加入uset中,然后分别统计数组中的最大值和最小值,最后根据最大值和最小值的差值是否超过5来判断返回true还是返回false。
bool IsContinuous( vector<int> numbers ) { // 集合 用于存储除0外的非重复元素 unordered_set<int> uset; // 统计最大值 最小值 数值范围1~14 int maxn=-1,minx=15; // 遍历数组元素 for(int i=0;i<numbers.size();i++) { // 如果遇到0则跳过 if(numbers[i]==0) continue; // 遇到相同元素则返回false if(uset.find(numbers[i])!=uset.end()) return false; // 反之加入set else uset.emplace(numbers[i]); // 统计非0最大值 maxn=max(maxn,numbers[i]); // 统计非0最小值 minx=min(minx,numbers[i]); } // 如果最大值与最小值相差不超过5则一定可以构成顺子 return (maxn-minx+1)<=5?true:false; }