Day45:扑克牌顺子
剑指Offer_编程题——扑克牌顺子
题目描述:
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
具体要求:
时间限制: C/C++ 1秒,其他语言2秒 空间限制: C/C++32M,其他语言64M
具体实现:
思路一: 这个题可以先把整数数组排序,然后由于左端可能是大小王,所以右端开始往左判断。首尾各一个指针,当尾部指针的值比它左面的值恰好大1的情况下。不需要大小王,如果差值比1大的话,左端恰好有一个大小王的话,则把当前的尾部指针向后移一个位置。也就是用掉一个王,这样知道首尾指针相等的情况下,则该这幅牌就是顺子,如果不是顺子的话早就返回了。具体用java实现如下:
import java.util.*;
public class Solution{
public boolean isContinuous(int []numbers){
if(numbers.length <= 1)
return false;
Arrays.sort(numbers);
int begin = 0;
int end = numbers.length - 1;
boolean flag = false;
while(begin < end){
if(numbers[end] - numbers[end - 1] == 1)
end--;
else{
if(numbers[begin] == 0){
begin++;
numbers[end]--;
}else
break;
}
}
if(begin == end)
return true;
return flag;
}
}
代码效果图如图所示:
思路二: 接下来给大家介绍一种判断五个数字是否为连续的经典方法。最直观的就是把数组排序。值得注意的是:由于0可以当做任意的数字,我们可以用0区补充数组的空缺,如果排序之后的数组不是连续的。即相邻的两个数字相隔若干个数字,但只要我们有足够的0可以补满这两个数字的空缺,这个数字实际上还是连续的。例如:数组排序之后为{0,1,3,4,5},在1和3之间空缺了一个2,刚好我们有一个0,也就是我们可以把它当成2去填补这个空缺。因此我们还需要做以下几件是事:首先把数组排序,在统计数组中0的个数,最后统计排序之后的数组中相邻数字之间的空缺总数。如果空缺的总数小于或者等于0的个数,那么这个数组就是连续的,反之则不连续。另外,我们需要注意的是,如果数组中的非0数字重复出现,则该数组不是连续的。换成扑克牌的描述方式就是如果一副牌里含有对子,则肯定不是顺子。具体我们用java以及python两种语言将其实现: 1、首先我们用java实现以上思路:
import java.util.Arrays;
public class Solution{
public boolean isContinuous(int []numbers){
if(numbers == null || numbers.length == 0)
return false;
Arrays.sort(numbers);
int numberOfZero = 0;
int numberOfGap = 0;
for(int i = 0; i < numbers.length && numbers[i] == 0; i++){
numberOfZero++;
}
int low = numberOfZero;
int high = low + 1;
while(high < numbers.length){
if(numbers[low] == numbers[high])
return false;
numberOfGap += numbers[high] - numbers[low] - 1;
low = high;
high++;
}
return numberOfGap <= numberOfZero ? true:false;
}
}
代码效果图如图所示:
2、接下来我们用python将其实现:
class Solution:
def IsContinuous(self, numbers):
if not numbers:
return False
numbers.sort()
zeros = numbers.count(0)
gaps = 0
small = zeros
big = small + 1
while big < len(numbers):
if numbers[small] == numbers[big]:
return False
gaps += numbers[big] - numbers[small] - 1
small = big
big += 1
return gaps <= zeros
代码效果图如图所示:
在这里需要注意的是:代码中为什么是numbers[big] - numbers[small] - 1。因为0是来填补空缺的,如果空缺是1则不用填补。这个做法是我们看出不等于1的空缺有多少。 思路三: 在以上思路的基础上,我们首先对排序数组,然后统计数组中0的个数,最后就是统计排序后数组中相邻数字之间的空缺总数。如果空缺的总数小于或者等于0的个数,那么数组就是连续的,反之不连续。接下来我们用python将其实现:
class Solution:
def IsContinuous(self, numbers):
if not numbers:
return False
numbers.sort()
zeros = 0
pre = None
for num in numbers:
if num == 0:
zeros += 1
if not pre:
pre = num
elif num == pre:
return False
else:
diff = num - pre - 1
zeros -= diff
pre = num
if zeros < 0:
return False
return True
代码效果图如图所示:
思路四: 统计数组中最大值和最小值,0的个数和非0数字的个数。如果最大值和最小值之间的空位可以被0和剩余非0数字填满,则数组是连续的,否则不连续。我们用python将其实现:
class Solution:
def IsContinuous(self, numbers):
if not numbers:
return False
zeros, maxi, mini = 0, -1, 14
counts = 0
exist = set()
for num in numbers:
if num == 0:
zeros += 1
continue
if num in exist:
return False
if num > maxi:
maxi = num
if num < mini:
mini = num
counts += 1
exist.add(num)
return maxi - mini + 1 - counts <= zeros
代码效果图如图所示:
总结
本道题通过与上一道题类似,均是通过实际问题来考察我们对字符串的理解,我们对本题给出了四种解题思路,均分别用java和python将其实现。首先就是正常的思路解题。其次给大家介绍了一种很常用的思路。最后是统计数组中最大值和最小值,0的个数和非0数字的个数。如果最大值和最小值之间的空位可以被0和剩余非0数字填满,则数组是连续的,否则不连续。因此,我们在做题的时候,应该多次尝试各种方法,扩展自己的思维,写出优质的代码。总之,我们要继续加油,争取早日找到工作,Good Luck!!!
参考文献
[1] 扑克牌顺子 [2] qq_27668313 [3] 负雪明烛
- Enterprise Library 4.1学习笔记8----缓存应用程序块之FileDependency
- CSS实现按钮的两张图片的同步出现
- 完整部署CentOS7.2+OpenStack+kvm 云平台环境(6)--在线调整虚拟机的大小
- 关于vb中的容器
- 关于vb中的容器
- Mysql数据库之Binlog日志使用总结
- 揭秘新人机大战柯洁对手天壤 AI排名已力压Deepzen
- 一路走到java工程师,java都快出java9了,到底该如何学java?
- 网站发布合并bll问题的解决
- 痛并快乐着:浅谈大数据时代的分布式存储架构
- linux运维中的命令梳理(四)
- linux运维中的命令梳理(三)
- 轻松水印-批量提取exif信息加水印的工具
- Enterprise Library 4.1学习笔记7----缓存应用程序块之SqlDependency
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 如何在K8S上备份和恢复MySQL
- 学习 | Spring Cloud Config 从入门到精通
- 模仿百度新闻的一部分
- 腾讯云录音文件识别-iOS SDK
- ESP8266如何设置wifi。
- ESP8266搭建web服务器
- 关于持续交付中Git分支管理的思考
- 轻松应对并发问题,Newbe.Claptrap 框架中 State 和 Event 应该如何理解?
- 如何暂停一个正在运行的线程?
- WebMonitor采集端优化之路
- 美颜算法之自动祛斑算法实现 | 案例分享
- 附025.kubeadm部署Kubernetes更新证书
- 消息提示时间的格式化例子(小程序)
- 【Spark】用scala2.11编译打包构建镜像
- 移动端事件穿透的原理与解决方案