1. 程式人生 > >X of a Kind in a Deck of Cards 卡牌分組

X of a Kind in a Deck of Cards 卡牌分組

給定一副牌,每張牌上都寫著一個整數。

此時,你需要選定一個數字 X,使我們可以將整副牌按下述規則分成 1 組或更多組:

  • 每組都有 X 張牌。
  • 組內所有的牌上都寫著相同的整數。

僅當你可選的 X >= 2 時返回 true

示例 1:

輸入:[1,2,3,4,4,3,2,1]
輸出:true
解釋:可行的分組是 [1,1],[2,2],[3,3],[4,4]

示例 2:

輸入:[1,1,1,2,2,2,3,3]
輸出:false
解釋:沒有滿足要求的分組。

示例 3:

輸入:
[1] 輸出:false 解釋:沒有滿足要求的分組。

示例 4:

輸入:[1,1]
輸出:true
解釋:可行的分組是 [1,1]

示例 5:

輸入:[1,1,2,2,2,2]
輸出:true
解釋:可行的分組是 [1,1],[2,2],[2,2]


提示:

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

思路:首先由於每個分組的數字個數必須大於1,所以可以設定一個map,記錄每個數字(key)及其對應的次數(number),然後找出所有出現次數的最大公約數,如果公約數不為1,那麼返回true,否則返回false。這是因為如果公約數不為1,那麼一定可以把陣列分成每個組的大小為最大公約數的組,在每個組中一定都是相同的數。

參考程式碼:

class Solution {
public:
    int gcd(int n, int m) {
        if (m == 0) return n;
        return gcd(m, n%m);
    }
    bool hasGroupsSizeX(vector<int>& deck) {
        if (deck.size() <= 1) return false;
        unordered_map<int, int> m;
        for (int &i : deck) m[i]++;
        int smallest=m.begin()->second;
        for (auto p = m.begin(); p != m.end(); p++) {
            smallest = gcd(smallest, p->second);
        }
        return !(smallest==1);
    }
};