剑指Offer 面试题61. 扑克牌中的顺子(Java代码)

https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/

题目描述

从扑克牌中随机抽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,否则无论怎样都是拼不成一个连续的字串的。

  • 提交的时候,忽略了有重复数字的情况。
  • 一旦碰到了重复数字就要立马返回false。
  • 可以使用哈希表查重
class Solution {
    public boolean isStraight(int[] nums) {
        // 找到最小值和最大值,最大值和最小值之前不能相差太大
        int min = 14;
        int max = -1;
        Set<Integer> set = new HashSet<Integer>();

        for(int num:nums){
            if(num == 0) continue;
            if(set.contains(num)) return false;
            set.add(num);
            max = Math.max(max, num);
            min = Math.min(min, num);
        }

        // 只有最小值和最大值之间的距离不超过5,即为true
        return (max - min < 5);
    }
}

如果需要在两个数字之间求最大值,那么使用系统函数Math.max,可能效率高点,可读性也强。

还有一种做法,将数组进行排序,然后再进行遍历

class Solution {
    public boolean isStraight(int[] nums) {
        int joker = 0;
        Arrays.sort(nums); // 数组排序
        for(int i = 0; i < 4; i++) {
            if(nums[i] == 0) joker++; // 统计大小王数量
            else if(nums[i] == nums[i + 1]) return false; // 若有重复,提前返回 false
        }
        return nums[4] - nums[joker] < 5; // 最大牌 - 最小牌 < 5 则可构成顺子
    }
}

你可能感兴趣的:(剑指Offer)