【算法-剑指 Offer】61. 扑克牌中的顺子(排序;指针;元素连续性)

剑指 Offer 61. 扑克牌中的顺子 - 力扣(LeetCode)

文章起笔:2021年11月17日17:40:50

问题描述及示例

若干副扑克牌中 随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。

示例 1:
输入: [1,2,3,4,5]
输出: True

示例 2:
输入: [0,0,1,2,5]
输出: True

注意:
数组长度为 5
数组的数取值为 [0, 13] .

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的题解(排序;指针)

首先先对 nums 数组进行排序(升序和降序都可以,我选择升序)。

然后确定数组中有多少个 0 元素,并且用 zeroRear 指针标识最后一个 0 元素的位置(zeroRear 指针具体指向最后一个 0 元素的后一个元素)。同时 zeroRear 也有记录数组中有多少个可用的 0 的作用。

然后从 zeroRear 处开始遍历 nums 中的剩余元素。如果当前遍历元素和后一个元素相等,可以直接返回 false。否则的话,就开始利用之前记录的可用的 0 来尝试补全剩余的序列,看要使得当前状态的数组变为“顺子”需要几个 0

遍历完成后,如果发现上面我们对 0 元素需求量大于原数组可以提供给我们的数量,则说明原数组不能组成顺子,反之则可以。

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var isStraight = function(nums) {
  // 先对nums排序,这是关键一步
  nums.sort((a, b) => a - b);
  // zeroRear用于记录可用的 0 元素的末尾位置,也可以理解为记录数组中有多少可供调用的 0
  let zeroRear = 0;
  // 确定 0 元素的数量
  while(nums[zeroRear] === 0) {
    zeroRear++;
  }
  // 开始遍历剩余的元素,注意开始位置和结束位置,尤其是结束位置
  for(let i = zeroRear; i < nums.length - 1; i++) {
    // 如果当前遍历元素和后一个元素相等,可以直接返回 `false`
    if(nums[i] === nums[i + 1]) {
      return false;
    }
    // 否则的话,就尝试通过消耗原数组中给我们提供的0元素来凑成一个顺子
    zeroRear = zeroRear - (nums[i + 1] - nums[i] - 1);
  }
  // 如果最后发现原数组中的0元素不够用,则返回false,否则返回true
  return zeroRear < 0 ? false : true;
};


提交记录
执行结果:通过
执行用时:64 ms, 在所有 JavaScript 提交中击败了93.38%的用户
内存消耗:38.9 MB, 在所有 JavaScript 提交中击败了37.52%的用户
通过测试用例:203 / 203
时间:2021/11/17 17:44

整体思路比较简单,但是有好些细节的地方一开始没考虑清楚,边吃外卖边随意的敲,结果浪费了好几次提交……千万不要大意!

在这里插入图片描述

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

【更新结束】

更新:2021年11月17日17:44:21

参考:面试题61. 扑克牌中的顺子(集合 Set / 排序,清晰图解) - 扑克牌中的顺子 - 力扣(LeetCode)

【更新结束】

有关参考

暂无

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值