Description
Alice has a hand of cards, given as an array of integers.
Now she wants to rearrange the cards into groups so that each group is size W, and consists of W consecutive cards.
Return true if and only if she can.
Example 1:
Input: hand = [1,2,3,6,2,3,4,7,8], W = 3
Output: true
Explanation: Alice’s hand can be rearranged as [1,2,3],[2,3,4],[6,7,8].
Example 2:
Input: hand = [1,2,3,4,5], W = 4
Output: false
Explanation: Alice’s hand can’t be rearranged into groups of 4.
Note:
1 <= hand.length <= 10000
0 <= hand[i] <= 10^9
1 <= W <= hand.length
Problem URL
Solution
有个hand数组,表示手中牌,给一个W,让将手中的牌分到大小为W的组中,并且每个组中的数都是连续的。
Approach1:
Using a Tree map to contain the frequency of each card.
- Count number of different cards to a map c
- Loop from the smallest card number.
- Everytime we meet a new card i, we cut off i - i + W - 1 from the counter.
Time Complexity:
O(MlogM + MW)
, whereM
is the number of different cards.
But when W is very large, this solution could be very slow.
Code
class Solution {
public boolean isNStraightHand(int[] hand, int W) {
Map<Integer, Integer> map = new TreeMap<>();
for (int card : hand){
map.put(card, map.getOrDefault(card, 0) + 1);
}
for (int it : map.keySet()){
if (map.get(it) > 0){
for (int i = W - 1; i >= 0; i--){
if (map.getOrDefault(it + i, 0) < map.get(it)){
return false;
}
map.put(it + i, map.get(it + i) - map.get(it));
}
}
}
return true;
}
}
Time Complexity: O()
Space Complexity: O()
Review
Approach 2:
What if W is huge, should we cut off card on by one?
Explanation:
- Count number of different cards to a map c
- Cur represent current opened straight groups.
- In a deque start, we record the number of opened a straight group.
- Loop from the smallest card number.
class Solution {
public boolean isNStraightHand(int[] hand, int W) {
Map<Integer, Integer> map = new TreeMap<>();
for (int card : hand){
map.put(card, map.getOrDefault(card, 0) + 1);
}
Queue<Integer> start = new LinkedList<>();
int lastChecked = -1, opened = 0;
for (int it : map.keySet()){
if (opened > 0 && it > lastChecked + 1 || opened > map.get(it)){
return false;
}
start.add(map.get(it) - opened);
lastChecked = it;
opened = map.get(it);
if (start.size() == W){
opened -= start.remove();
}
}
return opened == 0;
}
}