题目
2.思路
模拟 + 哈希表 + 优先队列(堆)
为了方便,我们令 m = groupSizem=groupSize。
题目要求我们将 handhand 分为若干份大小为 mm 的顺子。
在给定 handhand 的情况下,划分方式唯一确定,因此本质上这是一个「模拟」的过程。
具体的,我们可以使用「哈希表」对 handhand 中的数值进行「出现次数」统计,并用于后续 实时 维护剩余元素的出现次数。
然后使用优先队列维护(小根堆)所有的 hand[i]hand[i]。每次从优先队列(堆)中取出堆顶元素 tt 来 尝试作为「顺子」的发起点/首个元素(当然 tt 能够作为发起点的前提是 tt 仍是剩余元素,即实时维护的出现次数不为 00 ),然后用 tt 作为发起点/首个元素构造顺子,即对 [t, t + 1, … , t + m - 1][t,t+1,…,t+m−1] 元素的出现次数进行 -1−1 操作。
若构造过程中没有出现「剩余元素出现次数」不足以 -1−1 的话,说明整个构造过程没有冲突,返回 True,否则返回 False。
作者:AC_OIer
链接:https://leetcode-cn.com/problems/hand-of-straights/solution/gong-shui-san-xie-shu-ju-jie-gou-mo-ni-t-4hxw/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题解
class Solution {public boolean isNStraightHand(int[] hand, int m) {Map<Integer, Integer> map = new HashMap<>();PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->a-b);for (int i : hand) {map.put(i, map.getOrDefault(i, 0) + 1);q.add(i);}while (!q.isEmpty()) {int t = q.poll();if (map.get(t) == 0) continue;for (int i = 0; i < m; i++) {int cnt = map.getOrDefault(t + i, 0);if (cnt == 0) return false;map.put(t + i, cnt - 1);}}return true;}}作者:AC_OIer链接:https://leetcode-cn.com/problems/hand-of-straights/solution/gong-shui-san-xie-shu-ju-jie-gou-mo-ni-t-4hxw/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 时间复杂度:令 nn 为数组 hand 长度,使用哈希表进行次数统计的复杂度为 O(n)O(n);将所有元素从堆中存入和取出的复杂度为 O(n\log{n})O(nlogn)。整体复杂度为 O(n\log{n})O(nlogn)
- 空间复杂度:O(n)O(n)
