# 找到出现次数为K次的数

假设有一个数组中出现了一堆数,其中一个数出现了 K次,其余的数出现了M次,其中K<M 且 M>1,要求找到数组中出现K次的数。

# 算法思想

下图M=3,K=2,3和2都出现3次,只有1出现2次。

我们将数组中的数的二进制每个位置的1使用等长的数组进行统计,统计完毕后让每个位置的总数模M如果不等于0则出现K次的数在该位置为1,使用该方式还原出现K次的数即可。

# 代码实现

func FindKTimesNum(arr []int, K, M int) int {
	if arr == nil || len(arr) == 0 { // 不存在出现K次数字的情况返回-1
		return -1
	}
	bitArr := make([]int, 64)
	for _, num := range arr {
		CountOneInBitArr(bitArr, num) // 统计每一个num对应位置的1
	}
	ans := GetAnsNumByKM(bitArr, K, M) // 还原出现K次数的数字,0时需要校验真是出现次数
	if ans !=0 {
		return ans
	}
	count := 0
	for _, num := range arr {
		if num == 0 {
			count++
		}
	}
	if count == K {
		return 0
	}
	return -1
}

func CountOneInBitArr(bitArr []int, num int) {
	var index uint = 0
	for index < 64 { // 遍历num的每一位,将为1的位置统计下来
		if (num>>index) & 1 != 0 {
			bitArr[index]++
		}
		index++
	}
}

func GetAnsNumByKM(bitArr []int, K, M int) int {
	ans := 0
	for i, v := range bitArr { // 遍历二进制数组,找到目标数字每一位二进制为1的位置
		if v%M != 0 {
			ans |= 1<<uint(i)
		}
	}
	return ans
}
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
上次更新: 3/22/2024,