[LeetCode] 914. X of a Kind in a Deck of Cards 一副牌中的X



In a deck of cards, each card has an integer written on it.

Return true if and only if you can choose X >= 2 such that it is possible to split the entire deck into 1 or more groups of cards, where:

  • Each group has exactly X cards.
  • All the cards in each group have the same integer.

Example 1:

Input: [1,2,3,4,4,3,2,1]
Output: true
Explanation: Possible partition [1,1],[2,2],[3,3],[4,4]

Example 2:

Input: [1,1,1,2,2,2,3,3]
Output: false Explanation: No possible partition.

Example 3:

Input: [1]
Output: false Explanation: No possible partition.

Example 4:

Input: [1,1]
Output: true Explanation: Possible partition [1,1]

Example 5:

Input: [1,1,2,2,2,2]
Output: true Explanation: Possible partition [1,1],[2,2],[2,2]

Note:

  1. 1 <= deck.length <= 10000
  2. 0 <= deck[i] < 10000

這道題給了一堆牌,問我們能不能將這副牌分成若干堆,每堆均有X個,且每堆的牌數字都相同(這里不考慮花色)。既然要將相同的牌歸類,肯定要統計每種牌出現的個數,所以使用一個 HashMap 來建立牌跟其出現次數之間的映射。由於每堆X個,則若果某張牌的個數小於X,則肯定無法分,所以X的范圍是可以確定的,為 [2, mn],其中 mn 是數量最少的牌的個數。遍歷一遍 HashMap,找出最小的映射值 mn,若 mn 小於2,可以直接返回 false。否則就從2遍歷到 mn,依次來檢驗候選值X。檢驗的方法是看其他每種牌的個數是否能整除候選值X,不一定非要相等,比如 [1, 1, 2, 2, 2, 2], K=2 時就可以分為三堆 [1, 1], [2, 2], [2, 2],即相同的牌也可以分到其他堆里,所以只要每種牌的個數能整除X即可,一旦有牌數不能整除X了,則當前X一定不行,還得繼續檢驗下一個X值;若所有牌數都能整除X,可以返回 true。循環結束后返回 false,參見代碼如下:
解法一:
class Solution {
public:
    bool hasGroupsSizeX(vector<int>& deck) {
		unordered_map<int, int> cardCnt;
		for (int card : deck) ++cardCnt[card];
		int mn = INT_MAX;
		for (auto &a : cardCnt) mn = min(mn, a.second);
        if (mn < 2) return false;
        for (int i = 2; i <= mn; ++i) {
            bool success = true;
            for (auto &a : cardCnt) {
                if (a.second % i != 0) {
                    success = false;
                    break;
                }
            }
            if (success) return true;
        }
		return false;
    }
};

上面的解法是博主自己的解法,論壇上好多人使用了一個基於最大公約數 Greatest Common Divisor 的解法,寫起來很簡潔,但需要記住最大公約函數的寫法,或者直接使用內置的 gcd 函數(感覺有點耍賴哈~)。其實原理都差不多,這里是找每種牌數之間的最大公約數,只要這個 gcd 是大於1的,就表示可以找到符合題意的X,參見代碼如下:
解法二:
class Solution {
public:
    bool hasGroupsSizeX(vector<int>& deck) {
        unordered_map<int, int> cardCnt;
        for (int card : deck) ++cardCnt[card];
        int res = 0;
        for (auto &a : cardCnt) {
            res = gcd(a.second, res);
        }
        return res > 1;
    }
    int gcd(int a, int b) {
        return a == 0 ? b : gcd(b % a, a);
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/914


參考資料:

https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/

https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/discuss/175845/C%2B%2BJavaPython-Greatest-Common-Divisor

https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/discuss/309992/Java-Easy-to-understand-2-ms-faster-than-98.92-38.5-MB-less-than-99.23


[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM