Skip to content

Latest commit

 

History

History
201 lines (180 loc) · 6.06 KB

61.扑克牌顺子.md

File metadata and controls

201 lines (180 loc) · 6.06 KB

60.扑克牌顺子

题目描述

扑克牌可以组成顺子,大\小 王可以看成任何数字,并且A看作1,J11,Q12,K135张牌【A,0,3,0,5】就可以变成“1,2,3,4,5”(大小王分别看作24),这样就组成了顺子。(可以认为大小王是0。)

输入五张牌,如果牌能组成顺子就输出true,否则就输出false

示例1

输入

[0,3,2,6,4]

返回值

true

思路 & 解答

第一种思路,先排序,0肯定是靠左边,然后统计0的个数,后面的数,按照第一个非0的数进行递增,如果不是递增,则需要使用0牌补充,如果0牌不够,需要放回false,否则知道遍历完数组,返回true

    public boolean IsContinuous(int[] numbers) {
        // 数组长度不符合直接返回
        if (numbers == null || numbers.length < 5) {
            return false;
        }
        // 先排序
        Arrays.sort(numbers);
        // 统计0的个数
        int numOfZero = 0;
        // 初始化索引
        int start;
        // 统计0的个数
        for (start = 0; start < numbers.length; start++) {
            if (numbers[start] == 0) {
                numOfZero++;
            } else {
                // 非0的时候跳出
                break;
            }
        }
        // 暂存0的个数
        int n = numOfZero;
        // 当前的数值
        int cur = numbers[numOfZero];
        // 从0的下两个位置开始
        for (start++; start < numbers.length; ) {
            // 如果可变的牌数量为0
            if (numOfZero == 0) {
                // 和前面的一个对比
                if (numbers[start] != cur + 1) {
                    // 不等于当前数值+1的话,直接返回false
                    return false;
                } else {
                    // 当前数值+1
                    cur++;
                }

            } else {
                // 不等于当前数值+1的话,直接返回false
                if (numbers[start] != cur + 1) {
                    // 可变牌数量-1
                    numOfZero--;
                    //当前值+1
                    cur++;
                    // 遍历下一张牌
                    continue;
                } else {
                    // 相等则直接将当前值+1
                    cur++;
                }
            }
            // 索引滑动到下一张牌
            start++;
        }
        return true;
    }

C++ 代码如下:

class Solution {
public:
    bool IsContinuous( vector<int> numbers ) {
        // 数组长度不符合直接返回
        if (numbers.size() < 5) {
            return false;
        }
        // 先排序
        sort(numbers.begin(), numbers.end());  
        // 统计0的个数
        int numOfZero = 0;
        // 初始化索引
        int start;
        // 统计0的个数
        for (start = 0; start < numbers.size(); start++) {
            if (numbers[start] == 0) {
                numOfZero++;
            } else {
                // 非0的时候跳出
                break;
            }
        }
        // 暂存0的个数
        int n = numOfZero;
        // 当前的数值
        int cur = numbers[numOfZero];
        // 从0的下两个位置开始
        for (start++; start < numbers.size(); ) {
            // 如果可变的牌数量为0
            if (numOfZero == 0) {
                // 和前面的一个对比
                if (numbers[start] != cur + 1) {
                    // 不等于当前数值+1的话,直接返回false
                    return false;
                } else {
                    // 当前数值+1
                    cur++;
                }

            } else {
                // 不等于当前数值+1的话,直接返回false
                if (numbers[start] != cur + 1) {
                    // 可变牌数量-1
                    numOfZero--;
                    //当前值+1
                    cur++;
                    // 遍历下一张牌
                    continue;
                } else {
                    // 相等则直接将当前值+1
                    cur++;
                }
            }
            // 索引滑动到下一张牌
            start++;
        }
        return true;
    }
};

另外一种做法,初始化一个最小牌14,最大牌0,直接使用set保存数组的元素,如果set中已经存在该元素,那么我们直接放回false,如果set中不存在该元素,则将该元素放进set中,判断该元素是否小于最小牌,小于则更新最小牌,判断该元素是否大于最大牌,如果大于最大牌,则更新当前最大牌。

import java.util.HashSet;

public class Solution45 {

    public boolean IsContinuous(int [] numbers) {
        if(numbers==null||numbers.length<5){
            return false;
        }
        HashSet<Integer>set = new HashSet<>();
        int min = 14;
        int max = 0;
        for(int i=0;i<numbers.length;i++){
            if(numbers[i]!=0){
                if(set.contains(numbers[i])){
                    return false;
                }
                set.add(numbers[i]);
                max= Math.max(max,numbers[i]);
                min = Math.min(min,numbers[i]);
            }
        }
        return max-min<5;
    }
}

C++代码如下:

class Solution {
public:
    bool IsContinuous(vector<int> numbers) {
        if (numbers.size() < 5) {
            return false;
        }
        set<int> set;
        int minValue = 14;
        int maxValue = 0;
        for (int i = 0; i < numbers.size(); i++) {
            if (numbers[i] != 0) {
                if (set.count(numbers[i]) > 0) {
                    return false;
                }
                set.insert(numbers[i]);
                maxValue = max(maxValue, numbers[i]);
                minValue = min(minValue, numbers[i]);
            }
        }
        return maxValue - minValue < 5;
    }
};

借助了set,空间为5,空间复杂度是常数,可以认为是O(1),时间复杂度也是O(1)