文章

846. 一手顺子

问题846 一手顺子 ★★☆☆☆

https://leetcode-cn.com/problems/hand-of-straights/

首先,根据题目要求,如果hand包含的元素值个数不能被groupSize整除,那么显然不能满足分组要求。那么接下来该如何判断是否能满足分组要求呢?我的直觉是先计数,统计每个元素出现的次数。然后我只能想到比较暴力的解法就是按元素值从小到大(因此计数元素个数的map需要使用TreeMap),以groupSize为单元,扣减计数。如果处理到某个元素时当前groupSize大小的单元内不足扣减,或者全部处理完后还有元素的计数大于0,那么就不能满足分组要求,否则就可以满足分组要求。按照这个思路写了一版代码,提交以后也能通过。

看了下官方题解,整体思路上有一些共通之处,但是官方题解里先排序,然后以排序后的hand为遍历对象的处理显然更好,代码更简洁更优雅一些,更能体现贪婪算法的思想。这个题目蛮有意思的,很好的体现了贪婪算法的思想。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
	public boolean isNStraightHand(int[] hand, int groupSize) {
		int len = hand.length;
		if (len % groupSize != 0) {
			return false;
		}

		Arrays.sort(hand);

		Map<Integer, Integer> cnt = new HashMap<>();
		for (int val : hand) {
			cnt.put(val, cnt.getOrDefault(val, 0) + 1);
		}

		for (int val : hand) {
			boolean contains = cnt.containsKey(val);
			if (!contains) {
				continue;
			}

			for (int i = 0; i < groupSize; i++) {
				int neededVal = val + i;
				contains = cnt.containsKey(neededVal);
				if (!contains) {
					return false;
				} else {
					int valCnt = cnt.get(neededVal);
					--valCnt;
					if (valCnt > 0) {
						cnt.put(neededVal, valCnt);
					} else {
						cnt.remove(neededVal);
					}
				}
			}
		}

		return true;
	}

在 LeetCode 查看

本文由作者按照 CC BY 4.0 进行授权