2341-数组能形成多少数对

Raphael Liu Lv10

给你一个下标从 0 开始的整数数组 nums 。在一步操作中,你可以执行以下步骤:

  • nums 选出 两个 相等的 整数
  • nums 中移除这两个整数,形成一个 数对

请你在 nums 上多次执行此操作直到无法继续执行。

返回一个下标从 0 开始、长度为 2 的整数数组 answer 作为答案,其中 __answer[0] __
是形成的数对数目,answer[1] 是对 nums 尽可能执行上述操作后剩下的整数数目。

示例 1:

**输入:** nums = [1,3,2,1,3,2,2]
**输出:** [3,1]
**解释:**
nums[0] 和 nums[3] 形成一个数对,并从 nums 中移除,nums = [3,2,3,2,2] 。
nums[0] 和 nums[2] 形成一个数对,并从 nums 中移除,nums = [2,2,2] 。
nums[0] 和 nums[1] 形成一个数对,并从 nums 中移除,nums = [2] 。
无法形成更多数对。总共形成 3 个数对,nums 中剩下 1 个数字。

示例 2:

**输入:** nums = [1,1]
**输出:** [1,0]
**解释:** nums[0] 和 nums[1] 形成一个数对,并从 nums 中移除,nums = [] 。
无法形成更多数对。总共形成 1 个数对,nums 中剩下 0 个数字。

示例 3:

**输入:** nums = [0]
**输出:** [0,1]
**解释:** 无法形成数对,nums 中剩下 1 个数字。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

方法一:哈希表

思路

遍历一次数组,用一个哈希表保存元素个数的奇偶性,偶数为 false,奇数则为 true。每遇到一个元素,则将奇偶性取反,若取反完后为偶数个,则表明在上次偶数个之后又遇到了两个该元素,可以形成一个数对。最后返回一个数组,第一个元素是数对数,第二个元素是数组长度减去数对数的两倍。

代码

[sol1-Python3]
1
2
3
4
5
6
7
8
9
class Solution:
def numberOfPairs(self, nums: List[int]) -> List[int]:
cnt = defaultdict(bool)
res = 0
for num in nums:
cnt[num] = not cnt[num]
if not cnt[num]:
res += 1
return [res, len(nums) - 2 * res]
[sol1-Java]
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public int[] numberOfPairs(int[] nums) {
Map<Integer, Boolean> cnt = new HashMap<Integer, Boolean>();
int res = 0;
for (int num : nums) {
cnt.put(num, !cnt.getOrDefault(num, false));
if (!cnt.get(num)) {
res++;
}
}
return new int[]{res, nums.length - 2 * res};
}
}
[sol1-C#]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Solution {
public int[] NumberOfPairs(int[] nums) {
IDictionary<int, bool> cnt = new Dictionary<int, bool>();
int res = 0;
foreach (int num in nums) {
if (cnt.ContainsKey(num)) {
cnt[num] = !cnt[num];
} else {
cnt.Add(num, true);
}
if (!cnt[num]) {
res++;
}
}
return new int[]{res, nums.Length - 2 * res};
}
}
[sol1-C++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
vector<int> numberOfPairs(vector<int>& nums) {
unordered_map<int, bool> cnt;
int res = 0;
for (int num : nums) {
if (cnt.count(num)) {
cnt[num] = !cnt[num];
} else {
cnt[num] = true;
}
if (!cnt[num]) {
res++;
}
}
return {res, (int)nums.size() - 2 * res};
}
};
[sol1-C]
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
typedef struct {
int key;
bool val;
UT_hash_handle hh;
} HashItem;

HashItem *hashFindItem(HashItem **obj, int key) {
HashItem *pEntry = NULL;
HASH_FIND_INT(*obj, &key, pEntry);
return pEntry;
}

bool hashAddItem(HashItem **obj, int key, bool val) {
if (hashFindItem(obj, key)) {
return false;
}
HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
pEntry->key = key;
pEntry->val = val;
HASH_ADD_INT(*obj, key, pEntry);
return true;
}

bool hashSetItem(HashItem **obj, int key, bool val) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
hashAddItem(obj, key, val);
} else {
pEntry->val = val;
}
return true;
}

bool hashGetItem(HashItem **obj, int key, bool defaultVal) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
return defaultVal;
}
return pEntry->val;
}

void hashFree(HashItem **obj) {
HashItem *curr = NULL, *tmp = NULL;
HASH_ITER(hh, *obj, curr, tmp) {
HASH_DEL(*obj, curr);
free(curr);
}
}

int* numberOfPairs(int* nums, int numsSize, int* returnSize) {
HashItem *cnt = NULL;
int res = 0;
for (int i = 0; i < numsSize; i++) {
if (hashFindItem(&cnt, nums[i])) {
hashSetItem(&cnt, nums[i], !hashGetItem(&cnt, nums[i], false));
} else {
hashAddItem(&cnt, nums[i], true);
}
if (!hashGetItem(&cnt, nums[i], false)) {
res++;
}
}
hashFree(&cnt);
int *ans = (int *)malloc(sizeof(int) * 2);
ans[0] = res;
ans[1] = numsSize - 2 * res;
*returnSize = 2;
return ans;
}
[sol1-JavaScript]
1
2
3
4
5
6
7
8
9
10
11
var numberOfPairs = function(nums) {
const cnt = new Map();
let res = 0;
for (const num of nums) {
cnt.set(num, !(cnt.get(num) || false));
if (!cnt.get(num)) {
res++;
}
}
return [res, nums.length - 2 * res];
};
[sol1-Golang]
1
2
3
4
5
6
7
8
9
10
11
func numberOfPairs(nums []int) []int {
cnt := map[int]bool{}
res := 0
for _, num := range nums {
cnt[num] = !cnt[num]
if !cnt[num] {
res++
}
}
return []int{res, len(nums) - 2*res}
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。需要遍历一次数组。

  • 空间复杂度:O(n)。哈希表中最多保存 n 个元素。

 Comments
On this page
2341-数组能形成多少数对