feat(Go-Tool):2021/03/18:新增超过半数数字系列算法题,新增出现次数不同的数字系列算法题
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:46
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package numberList
|
||||||
|
|
||||||
|
type i interface {
|
||||||
|
Doc() string
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/18 13:08
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyOneNumberOtherKObj struct{}
|
||||||
|
|
||||||
|
func (*OnlyOneNumberOtherKObj) Doc() string {
|
||||||
|
return `
|
||||||
|
给定一个整型数组 arr和一个大于1的整数k。已知 arr中只有1个数出现了1次,其他的数都出现了k次,请返回只出现了1次的数。
|
||||||
|
|
||||||
|
【要求】
时间复杂度为 O(N),额外空间复杂度为 O(1)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnlyOneNumberOtherK(numList []int, k int) int {
|
||||||
|
bitList := make([]int, 32)
|
||||||
|
for _, num := range numList {
|
||||||
|
//把每个数字转换成二进制
|
||||||
|
store := make([]int, 32)
|
||||||
|
for i := 0; num != 0; i++ {
|
||||||
|
store[i] = num % k
|
||||||
|
num = num / k
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < 32; j++ {
|
||||||
|
//不进位加法
|
||||||
|
bitList[j] = (store[j] + bitList[j]) % k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//k进制转换回十进制
|
||||||
|
power := 1 //k的次方值
|
||||||
|
result := 0 //只出现一次的数字
|
||||||
|
for i, bit := range bitList {
|
||||||
|
power = 1
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
power = power * k
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result + power*bit
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/18 13:09
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyOneNumberOtherK(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 3, 4, 2, 3, 4}, 2)) //1
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 3, 4, 2, 3, 4, 2, 3, 4}, 3)) //1
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 3, 4, 4, 5, 6, 2, 2, 3, 5, 5, 3, 4, 6, 6}, 3)) //1
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, 10)) //1
|
||||||
|
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 3, 3000, 4, 2, 3, 4}, 2)) //3000
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 3, 4, 2, 9999, 3, 4, 2, 3, 4}, 3)) //9999
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 3, 4, 4, 5, 6, 321, 2, 2, 3, 5, 5, 3, 4, 6, 6}, 3)) //321
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 2, 2, 2, 2, 2, 2, 5891, 2, 2, 2}, 10)) //5891
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 21:53
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyOneNumberOtherThreeObj struct{}
|
||||||
|
|
||||||
|
func (*OnlyOneNumberOtherThreeObj) Doc() string {
|
||||||
|
return `
|
||||||
|
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
|
||||||
|
要求:线性时间复杂度。 不使用额外空间来实现
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnlyOneNumberOtherThree1(numList []int) int {
|
||||||
|
bitList := make([]int, 32)
|
||||||
|
|
||||||
|
for _, num := range numList {
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
bitList[i] += (num >> i) & 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res := 0
|
||||||
|
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
if bitList[i]%3 != 0 {
|
||||||
|
res += 1 << i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
//通过二进制的方式,本质上就是要构造一个相应的回路,即出现num的次数分别从1~3应该是 01 -> 10 -> 00 ...
|
||||||
|
func OnlyOneNumberOtherThree2(numList []int) int {
|
||||||
|
|
||||||
|
var a uint
|
||||||
|
var b uint
|
||||||
|
|
||||||
|
//第一次出现num计算的结果 a = num ,b = 0
|
||||||
|
//第二次出现num计算的结果 a = 0 ,b = num
|
||||||
|
//第三次出现num计算的结果 a = num ,b = 0
|
||||||
|
//因此直接返回a即可
|
||||||
|
for _, num := range numList {
|
||||||
|
a = a ^ uint(num)&(^b)
|
||||||
|
b = b ^ uint(num)&(^a)
|
||||||
|
}
|
||||||
|
return int(a)
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 21:55
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyOneNumberOtherThree1(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{1, 1, 1, 2, 2, 2, 3, 3, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{1, 15, 23, 67, 15, 67, 67, 23, 23, 14, 15, 1, 1})) //14
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{100, 200, 300, 4, 6, 100, 100, 6, 6, 4, 200, 300, 200, 300, 5, 4})) //5
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOnlyOneNumberOtherThree2(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{1, 1, 1, 2, 2, 2, 3, 3, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{1, 15, 23, 67, 15, 67, 67, 23, 23, 14, 15, 1, 1})) //14
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{100, 200, 300, 4, 6, 100, 100, 6, 6, 4, 200, 300, 200, 300, 5, 4})) //5
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 17:51
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyOneNumberShowOnceObj struct{}
|
||||||
|
|
||||||
|
func (*OnlyOneNumberShowOnceObj) Doc() string {
|
||||||
|
return `
|
||||||
|
一个整型数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
//通过异或解决
|
||||||
|
func OnlyOneNumberShowOnce(numberList []int) int {
|
||||||
|
result := 0
|
||||||
|
for _, num := range numberList {
|
||||||
|
result ^= num
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 17:52
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyOneNumberShowOnce(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{1, 2, 3, 2, 3, 4, 4})) //1
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{1, 2, 3, 2, 3, 4, 4, 1, 5})) //5
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{1, 2, 3, 2, 3, 4, 4, 1, 10})) //10
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{2, 2, 2, 2, 1, 3, 3, 3, 3})) //1
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 18:01
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyTwoNumberShowOnceObj struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*OnlyTwoNumberShowOnceObj) Doc() string {
|
||||||
|
return `
|
||||||
|
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnlyTwoNumberShowOnce(numList []int) (int, int) {
|
||||||
|
if len(numList) < 2 {
|
||||||
|
panic("数组长度不能小于两个")
|
||||||
|
}
|
||||||
|
result := 0
|
||||||
|
//先进行异或,得到异或的结果
|
||||||
|
for _, num := range numList {
|
||||||
|
result = result ^ num
|
||||||
|
}
|
||||||
|
//找到异或后为1的位置
|
||||||
|
pos := 0
|
||||||
|
for ; pos < 32; pos++ {
|
||||||
|
if ((result >> pos) & 1) == 1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
firstList := make([]int, 0)
|
||||||
|
secondList := make([]int, 0)
|
||||||
|
|
||||||
|
//根据异或位的结果,把数组分成两组
|
||||||
|
for _, num := range numList {
|
||||||
|
if ((num >> pos) & 1) == 1 {
|
||||||
|
firstList = append(firstList, num)
|
||||||
|
} else {
|
||||||
|
secondList = append(secondList, num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
first := 0
|
||||||
|
for _, num := range firstList {
|
||||||
|
first ^= num
|
||||||
|
}
|
||||||
|
second := 0
|
||||||
|
|
||||||
|
for _, num := range secondList {
|
||||||
|
second ^= num
|
||||||
|
}
|
||||||
|
|
||||||
|
return first, second
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 18:02
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyTwoNumberShowOnce(t *testing.T) {
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 1, 7})) //1,7
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 1, 7, 8, 9, 0, 19, 19, 0, 8, 9})) //1,7
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 1, 7, 5, 4, 3, 2})) //1,7
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 1, 7, 1, 100})) //1,100
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 15:45
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
type NumberMoreThanHalfObj struct{}
|
||||||
|
|
||||||
|
func (n *NumberMoreThanHalfObj) Doc() string {
|
||||||
|
return `
|
||||||
|
题目:
|
||||||
|
|
||||||
|
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
|
||||||
|
|
||||||
|
例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
|
||||||
|
|
||||||
|
要求:时间复杂度O(N),空间复杂度O(1)
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NumberMoreThanHalf(numList []int) int {
|
||||||
|
var number, count int
|
||||||
|
for _, j := range numList {
|
||||||
|
if number == j {
|
||||||
|
count++
|
||||||
|
} else if number != j && count <= 1 {
|
||||||
|
number = j
|
||||||
|
} else {
|
||||||
|
//number !=j && count >1
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//最后验证,确保一定超过
|
||||||
|
countValid := 0
|
||||||
|
for _, j := range numList {
|
||||||
|
if j == number {
|
||||||
|
countValid++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if countValid <= len(numList)/2 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return number
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:23
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNumberMoreThanHalf(t *testing.T) {
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3})) //-1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 1, 1})) //1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 1})) //-1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 2, 3, 2, 3, 3})) //-1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1})) //1
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:46
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
type NumberMoreThanKObj struct{}
|
||||||
|
|
||||||
|
func (*NumberMoreThanKObj) Doc() string {
|
||||||
|
return `
|
||||||
|
给定一个整型数组arr(数组长度为N) 与一个整数k,打印所有出现次数大于 N/K 的数。如果没有这样的数,返回-1。
|
||||||
|
|
||||||
|
要求:时间复杂度为O(N*K),额外空间复杂度为O(K)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NumberMoreThanK(numList []int, k int) []int {
|
||||||
|
//小于2的情况是肯定不会超过.
|
||||||
|
if k < 2 {
|
||||||
|
return []int{}
|
||||||
|
}
|
||||||
|
|
||||||
|
//用来保存数字与其出现次数
|
||||||
|
numMap := make(map[int]int, 0)
|
||||||
|
for _, num := range numList {
|
||||||
|
//如果不存在则数值设置为1
|
||||||
|
if _, ok := numMap[num]; !ok {
|
||||||
|
numMap[num] = 1
|
||||||
|
} else {
|
||||||
|
//存在则出现次数+1
|
||||||
|
numMap[num] = numMap[num] + 1
|
||||||
|
}
|
||||||
|
//当容器的大小为k
|
||||||
|
if len(numMap) == k {
|
||||||
|
for key, value := range numMap {
|
||||||
|
//个数正好等于1的要删掉,因为本次减一之后,就等于0了
|
||||||
|
if value == 1 {
|
||||||
|
delete(numMap, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//map的key是可能出现次数超过N/k的数
|
||||||
|
//这里主要是为了拿到key
|
||||||
|
for key := range numMap {
|
||||||
|
numMap[key] = 0
|
||||||
|
}
|
||||||
|
//重新计算对应数字的出现次数
|
||||||
|
for _, num := range numList {
|
||||||
|
if _, ok := numMap[num]; ok {
|
||||||
|
numMap[num]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//出现次数超过k次的判断
|
||||||
|
result := make([]int, 0)
|
||||||
|
for key, value := range numMap {
|
||||||
|
if value > len(numList)/k {
|
||||||
|
result = append(result, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:59
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNumberMoreThanK(t *testing.T) {
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 1}, 3)) //1
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 1}, 4)) //1,2,3
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3, 1, 2, 3, 1, 2, 3}, 2)) //
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3}, 2)) //
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user