数组中
一种数出现奇数次
其他都是是出现偶数次
找到奇数次的数
两种数出现奇数次
其他都是是出现偶数次
type Number interface {
int | int64 | byte
}
func findNumber[N Number](myArray []N) {
//异或操作。
var a = myArray[0]
for i := 1; i < len(myArray); i++ {
a = a ^ myArray[i]
}
fmt.Printf("%v", a)
}
func findNumberTwo[N Number](myArray []N) {
}
func main() {
var myArray = []int{1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8}
findNumber[int](myArray)
}
这里实际上是考异或的操作
就是计算机组成原理中的位操作
然后是
初步的排序
冒泡排序
type MyNumber interface {
int | int64 | int32 | byte | float32 | float64
}
func bubbleSort[M MyNumber](myArray []M) {
for j := 1; j < len(myArray); j++ {
for i := 0; i < len(myArray); i++ {
if myArray[i] > myArray[j] {
myArray[i], myArray[j] = myArray[j], myArray[i]
}
}
}
for i, m := range myArray {
fmt.Printf("%d %d\n", i, m)
}
}
插入排序
type MyNumber interface {
int | int64 | int32 | byte | float32 | float64
}
func insertSort[M MyNumber](myArray []M) {
for i := 1; i < len(myArray); i++ {
for j := 0; j < i; j++ {
if myArray[i] < myArray[j] {
myArray[i], myArray[j] = myArray[j], myArray[i]
}
}
}
for i, m := range myArray {
fmt.Printf("%d %d\n", i, m)
}
}
二分查找
这里有个特殊的地方
我尽量不去使用递归
因为有时候递归不知道变量怎么变化(就是自己写不来递归。和优化递归)
这里二分查找是找到相同元素最左边的地方
如果要最右边的地方。改>=为<=
func dichotomyFind[M MyNumber](myArray []M, find M) int {
var middle = len(myArray) / 2
var left = 0
var right = len(myArray)
var CPArray = make([]M, len(myArray))
copy(CPArray, myArray)
var check = 0
for {
//这里多找一一遍。如果两次都一样就跳出循环
if check != middle {
check = middle
} else if check == middle {
return middle
}
if CPArray[middle] >= find {
right = middle
middle = (right + left) / 2
} else if CPArray[middle] < find {
left = middle + 1
middle = (right + left) / 2
}
}
}
如果不要求最左边最右边
就直接找到就返回
func dichotomyFind[M MyNumber](myArray []M, find M) int {
var middle = len(myArray) / 2
var left = 0
var right = len(myArray)
var CPArray = make([]M, len(myArray))
copy(CPArray, myArray)
for {
if CPArray[middle] > find {
right = middle
middle = (right + left) / 2
} else if CPArray[middle] < find {
left = middle + 1
middle = (right + left) / 2
} else if CPArray[middle] == find {
return middle
}
}
}
链表
链表的基本
包括单链表、双向链表和循环链表。
创建、增加节点、删除节点、单链表逆置、合并有序链表
快慢指针
额外数据结构记录(哈希表等)
合并有序单链表
判断链表是否有环
回文链表
复制含有随机指针节点的链表
两个单链表相交的一系列问题
定义泛型
```go
type Value interface {
int | int8 | byte | float64 | float32 | int64
}
//单链表节点
type Node[v Value] struct {
V v
next *Node[v]
}
//双向链表节点
type BidirectionalNode[v Value] struct {
V v
F *BidirectionalNode[v]
N *BidirectionalNode[v]
}
创建链表
func (n *Node[Value]) CreateNormalLinkedList(data []Value) *Node[Value] {
var tem = n
for _, datum := range data {
var newN = new(Node[Value])
newN.V = datum
newN.next = nil
tem.next = newN
tem = newN
}
return n
}
创建环形链表
func (n *Node[Value]) CreateNormalRingList(data []Value, position int) *Node[Value] {
var tem = n
var ringNode = n
for p, datum := range data {
var newN = new(Node[Value])
newN.V = datum
newN.next = nil
tem.next = newN
tem = newN
if p == position {
ringNode = newN
}
}
tem.next = ringNode
return n
}
循环输出不是环形代码
func (n *Node[Value]) PrintNormalLinkedList() {
var tem = n
for {
if tem == nil {
break
}
fmt.Printf("%v \n", tem.V)
tem = tem.next
}
}
插入
func (n *Node[Value]) InsertInNormal(insert Value, position int) {
//看插入的位置。因为我这个头结点是记录的长度
var tem = n
var one Value = 1
n.V = add(n.V, one)
for i := 0; i < (position - 1); i++ {
tem = tem.next
}
if tem.next == nil {
var newN = new(Node[Value])
newN.V = insert
newN.next = nil
tem.next = newN
} else if tem.next != nil {
var newN = new(Node[Value])
newN.V = insert
newN.next = tem.next
tem.next = newN
}
}
删除
func (n *Node[Value]) DeleteInNormal(delete Value) {
var tem = n
var one Value = 1
n.V = reduce(n.V, one)
for {
if tem.next.V == delete {
break
} else {
tem = tem.next
}
}
tem.next = tem.next.next
}
单链表逆置,双指针头插法
func (n *Node[Value]) SinglyLinkedListInversion() {
var onePointer = n.next.next
var twoPointer = n.next.next
var head = n.next
head.next = nil
for {
twoPointer = twoPointer.next
onePointer.next = head
head = onePointer
onePointer = twoPointer
if twoPointer == nil {
break
}
}
n.next = head
}
合并有序链表
func Compare[v Value](a v, b v) (result bool) {
if a >= b {
result = true
} else if a < b {
result = false
}
return result
}
func MergeOrderedList[v Value](headOne *Node[v], headTwo *Node[v]) (mergeList *Node[v]) {
var temOne = headOne.next
var temTwo = headTwo.next
mergeList = new(Node[v])
mergeList.V = add(headOne.V, headTwo.V)
mergeList.next = nil
var mergeHead = mergeList
for {
if temTwo == nil {
break
} else if temOne == nil {
break
}
if Compare(temOne.V, temTwo.V) == true {
mergeList.next = temTwo
mergeList = mergeList.next
temTwo = temTwo.next
} else if Compare(temOne.V, temTwo.V) == false {
mergeList.next = temOne
mergeList = mergeList.next
temOne = temOne.next
}
}
if temTwo != nil {
mergeList.next = temTwo
} else if temOne != nil {
mergeList.next = temOne
}
return mergeHead
}
判断是否有环
额外空间MAP
func RingLinkedListWithMap[v Value](head *Node[v]) (IsRing bool, RingNode *Node[v]) {
var checkMap = make(map[*Node[v]]int)
var i = 0
var tem = head
for {
checkMap[tem] = i
i = i + 1
tem = tem.next
if tem == nil {
IsRing = false
RingNode = nil
break
} else if _, ok := checkMap[tem]; ok == true {
IsRing = true
RingNode = tem
break
}
}
fmt.Printf("%v %v \n", IsRing, RingNode.V)
return false, RingNode
}
快慢指针
func RingLinkedListWithFastAndSlowPointer[v Value](head *Node[v]) (IsRing bool, RingNode *Node[v]) {
var slowPointer = head.next
var fastPointer = head.next
var tem = head.next
for {
slowPointer = slowPointer.next
fastPointer = fastPointer.next.next
if fastPointer == nil {
IsRing = false
RingNode = nil
break
} else if fastPointer == slowPointer {
IsRing = true
fastPointer = tem
for {
slowPointer = slowPointer.next
fastPointer = fastPointer.next
if fastPointer == slowPointer {
RingNode = fastPointer
break
}
}
break
}
}
fmt.Printf("%v %v \n", IsRing, RingNode.V)
return IsRing, RingNode
}