Skip to content

Commit f4db689

Browse files
committed
Added Solutions to Leetcode 914
1 parent 29870a9 commit f4db689

File tree

2 files changed

+265
-1
lines changed

2 files changed

+265
-1
lines changed

dsa-problems/leetcode-problems/0900-0999.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export const problems = [
9999
problemName: "914. X of a Kind in a Deck of Cards",
100100
difficulty: "Easy",
101101
leetCodeLink: "https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards",
102-
solutionLink: "#"
102+
solutionLink: "/dsa-solutions/lc-solutions/0900-0999/x-of-a-kind-in-a-deck-of-cards"
103103
},
104104
{
105105
problemName: "915. Partition Array into Disjoint Intervals",
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
---
2+
id: x-of-a-kind-in-a-deck-of-cards
3+
title: X of a Kind in a Deck of Cards
4+
sidebar_label: 0914 - X of a Kind in a Deck of Cards
5+
tags:
6+
- Math
7+
- Hash Table
8+
- Array
9+
description: "This is a solution to the X of a Kind in a Deck of Cards problem on LeetCode."
10+
---
11+
12+
## Problem Description
13+
14+
You are given an integer array deck where `deck[i]` represents the number written on the $i^th$ card.
15+
16+
Partition the cards into **one or more groups** such that:
17+
18+
- Each group has **exactly** `x` cards where `x > 1`, and
19+
- All the cards in one group have the same integer written on them.
20+
21+
Return `true` if such partition is possible, or `false` otherwise.
22+
23+
24+
### Examples
25+
26+
**Example 1:**
27+
28+
```
29+
Input: deck = [1,2,3,4,4,3,2,1]
30+
Output: true
31+
Explanation: Possible partition [1,1],[2,2],[3,3],[4,4].
32+
```
33+
**Example 2:**
34+
35+
```
36+
Input: deck = [1,1,1,2,2,2,3,3]
37+
Output: false
38+
Explanation: No possible partition.
39+
```
40+
41+
### Constraints
42+
43+
- $1 \leq deck.length \leq 10^4$
44+
- $0 \leq deck[i] < 10^4$
45+
46+
## Solution for X of a Kind in a Deck of Cards
47+
48+
## Approach 1: Brute Force
49+
### Intuition
50+
51+
We can try every possible `X`.
52+
53+
### Algorithm
54+
55+
Since we divide the deck of `N` cards into say, `K` piles of `X` cards each, we must have `N % X == 0`.
56+
57+
Then, say the deck has `C_i` copies of cards with number `i`. Each group with number `i` has `X` copies, so we must have `C_i % X == 0`. These are necessary and sufficient conditions.
58+
59+
### Code in Different Languages
60+
61+
<Tabs>
62+
<TabItem value="cpp" label="C++">
63+
<SolutionAuthor name="@Shreyash3087"/>
64+
65+
```cpp
66+
class Solution {
67+
public:
68+
bool hasGroupsSizeX(vector<int>& deck) {
69+
int N = deck.size();
70+
vector<int> count(10000, 0);
71+
for (int c : deck)
72+
count[c]++;
73+
74+
vector<int> values;
75+
for (int i = 0; i < 10000; ++i)
76+
if (count[i] > 0)
77+
values.push_back(count[i]);
78+
79+
for (int X = 2; X <= N; ++X) {
80+
if (N % X == 0) {
81+
bool valid = true;
82+
for (int v : values) {
83+
if (v % X != 0) {
84+
valid = false;
85+
break;
86+
}
87+
}
88+
if (valid)
89+
return true;
90+
}
91+
}
92+
93+
return false;
94+
}
95+
};
96+
97+
98+
```
99+
</TabItem>
100+
<TabItem value="java" label="Java">
101+
<SolutionAuthor name="@Shreyash3087"/>
102+
103+
```java
104+
class Solution {
105+
public boolean hasGroupsSizeX(int[] deck) {
106+
int N = deck.length;
107+
int[] count = new int[10000];
108+
for (int c: deck)
109+
count[c]++;
110+
111+
List<Integer> values = new ArrayList();
112+
for (int i = 0; i < 10000; ++i)
113+
if (count[i] > 0)
114+
values.add(count[i]);
115+
116+
search: for (int X = 2; X <= N; ++X)
117+
if (N % X == 0) {
118+
for (int v: values)
119+
if (v % X != 0)
120+
continue search;
121+
return true;
122+
}
123+
124+
return false;
125+
}
126+
}
127+
```
128+
129+
</TabItem>
130+
<TabItem value="python" label="Python">
131+
<SolutionAuthor name="@Shreyash3087"/>
132+
133+
```python
134+
class Solution(object):
135+
def hasGroupsSizeX(self, deck):
136+
count = collections.Counter(deck)
137+
N = len(deck)
138+
for X in xrange(2, N+1):
139+
if N % X == 0:
140+
if all(v % X == 0 for v in count.values()):
141+
return True
142+
return False
143+
```
144+
</TabItem>
145+
</Tabs>
146+
147+
### Complexity Analysis
148+
149+
#### Time Complexity: $O(N^2log(logN))$
150+
151+
> **Reason**: where N is the number of cards. It is outside the scope of this article to prove that the number of divisors of N is bounded by $O(Nlog(⁡log⁡N))$.
152+
153+
#### Space Complexity: $O(N)$
154+
155+
> **Reason**: The space needed to store the counts of each card type in the `values` list.
156+
157+
## Approach 2: Greatest Common Divisor
158+
### Intuition and Algorithm
159+
160+
Again, say there are `C_i` cards of number `i`. These must be broken down into piles of `X` cards each, ie. `C_i % X == 0` for all `i`.
161+
162+
Thus, `X` must divide the greatest common divisor of `C_i`. If this greatest common divisor `g` is greater than `1`, then `X = g` will satisfy. Otherwise, it won't.
163+
164+
### Code in Different Languages
165+
166+
<Tabs>
167+
<TabItem value="cpp" label="C++">
168+
<SolutionAuthor name="@Shreyash3087"/>
169+
170+
```cpp
171+
class Solution {
172+
public:
173+
bool hasGroupsSizeX(vector<int>& deck) {
174+
vector<int> count(10000, 0);
175+
for (int c : deck)
176+
count[c]++;
177+
178+
int g = -1;
179+
for (int i = 0; i < 10000; ++i)
180+
if (count[i] > 0) {
181+
if (g == -1)
182+
g = count[i];
183+
else
184+
g = gcd(g, count[i]);
185+
}
186+
187+
return g >= 2;
188+
}
189+
190+
int gcd(int x, int y) {
191+
return x == 0 ? y : gcd(y % x, x);
192+
}
193+
};
194+
195+
```
196+
</TabItem>
197+
<TabItem value="java" label="Java">
198+
<SolutionAuthor name="@Shreyash3087"/>
199+
200+
```java
201+
class Solution {
202+
public boolean hasGroupsSizeX(int[] deck) {
203+
int[] count = new int[10000];
204+
for (int c: deck)
205+
count[c]++;
206+
207+
int g = -1;
208+
for (int i = 0; i < 10000; ++i)
209+
if (count[i] > 0) {
210+
if (g == -1)
211+
g = count[i];
212+
else
213+
g = gcd(g, count[i]);
214+
}
215+
216+
return g >= 2;
217+
}
218+
219+
public int gcd(int x, int y) {
220+
return x == 0 ? y : gcd(y%x, x);
221+
}
222+
}
223+
```
224+
225+
</TabItem>
226+
<TabItem value="python" label="Python">
227+
<SolutionAuthor name="@Shreyash3087"/>
228+
229+
```python
230+
class Solution(object):
231+
def hasGroupsSizeX(self, deck):
232+
from fractions import gcd
233+
vals = collections.Counter(deck).values()
234+
return reduce(gcd, vals) >= 2
235+
```
236+
</TabItem>
237+
</Tabs>
238+
239+
### Complexity Analysis
240+
241+
#### Time Complexity: $O(Nlog^2(N))$
242+
243+
> **Reason**: where N is the number of votes. If there are $C_i$ cards with number i, then each gcd operation is naively $O(\log^2 C_i)$. Better bounds exist, but are outside the scope of this article to develop
244+
245+
#### Space Complexity: $O(N)$
246+
247+
> **Reason**: The space needed to store the counts of each card type in the `values` list.
248+
249+
250+
251+
## Video Solution
252+
253+
<LiteYouTubeEmbed
254+
id="wN_BIEB73Jc"
255+
params="autoplay=1&autohide=1&showinfo=0&rel=0"
256+
title="LeetCode 914. X of a Kind in a Deck of Cards"
257+
poster="hqdefault"
258+
webp />
259+
260+
## References
261+
262+
- **LeetCode Problem**: [X of a Kind in a Deck of Cards](https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/description/)
263+
264+
- **Solution Link**: [X of a Kind in a Deck of Cards](https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/solutions/)

0 commit comments

Comments
 (0)