资讯动态

go算法题

发布时间:2026/10/30 1:14:35 来源:尧图企业网站定制
//**冒泡排序package mainimport fmtfunc BubbleSort(arr []int){n:len(arr)temp:0for i:0;in-1;i{for j:i1;jn;j{if arr[j]arr[i]{temparr[i]arr[i]arr[j]arr[j]temp}}}}func main() {nums : []int{64, 34, 25, 12, 22, 11, 90}BubbleSort(nums)fmt.Println(nums)}//三种排序 选择排序 8万数据 用时:12秒// 插入排序 8万数据 用时:4秒// 快速排序 8万数据 用时:0秒//**选择排序package mainimport fmtfunc selectionSort(arr []int) {n : len(arr)for i : 0; i n-1; i {k : ifor j : i 1; j n; j {if arr[j] arr[k] {k j}}arr[i], arr[k] arr[k], arr[i]}}func main() {arr : []int{64, 34, 25, 12, 22, 11, 90}fmt.Println(选择排序前:, arr)selectionSort(arr)fmt.Println(选择排序后:, arr)}//*插入排序func InsertSort(arr []int){n:len(arr)for i:1;in;i{tmp:arr[i]j:i-1for j0 arr[j]tmp{arr[j1]arr[j]jj-1}arr[j1]tmp}}func main(){arr:[]int{2,34,5,65,6}InsertSort(arr)fmt.Println(arr)}//left 表示 数组左边的下标//right 表示 数组右边的下标//arr 表示要排序的数组//*快速排序 func quickSortV2(arr []int, low, hight int) { if low hight { return } left, right : low, hight pivot : arr[(lowhight)/2] // 这里的经验值取的是中间数经过 Benchmark 测试确实比较优秀 for left right { // 从左边开始迭代 // 左边的数如果比 pivot 小那么就应该将他放在左边继续向右滑动遇到一个比他大的为止 for arr[left] pivot { left } // 右边的数如果比 pivot 大那么就应该将他放在右边继续向左滑动遇到一个比他小的为止 for arr[right] pivot { right-- } // 这里进行一次交换将上面碰到的大数和小数交换一次 //left 继续右走right 继续左走 注意这里还不一定相遇去继续执行上面的逻辑 if left right { arr[left], arr[right] arr[right], arr[left] left right-- } } quickSortV2(arr, low, right) quickSortV2(arr, left, hight) } ///////////////// package main import fmt func main() { fmt.Println(Hello, World!) arr : [6]int{-9,78,0,23,-576,70} quickSort(arr,0,len(arr)-1) } func quickSort(arr [6]int, left, right int) { if left right { return } cur, lo : left1, left for cur right { if arr[cur] arr[left] { arr[lo1], arr[cur] arr[cur], arr[lo1] lo } cur } arr[left], arr[lo] arr[lo], arr[left] quickSort(arr, left, lo-1) quickSort(arr, lo1, right) //fmt.Println(arr) //return } //这个版本是所有快速排序中看起来比较难以理解只有一个指针从左到右滑动设计非常巧妙。///*递归使用package main import fmt // Go的递归调用和类型转换 // 递归就是在运行的过程中调用自己。 func Factorial(x int) (result int) { if x 0 { result 1; } else { result x * Factorial(x - 1); } return; } func Fibonacci(n int) int { if n 2 { return n } return Fibonacci(n-2) Fibonacci(n-1) } func main(){ // go语言的递归样例 //go语言实现阶乘 var num int 10 fmt.Println(Factorial(num)) // go实现斐波那契 fmt.Println(Fibonacci(num)) }//*二分package main import fmt func BinarySearch(arr *[6]int,leftIndex int,rightIndex int ,findVal int ){ if leftIndex rightIndex{ fmt.Printf(%v中找不到\t元素%v\n,(*arr),findVal) return } //先找到中间下标 midddle : (leftIndexrightIndex)/2 if (*arr)[midddle] findVal { //说明要查找的数在左边 就应该向 leftIndex ---- (middle - 1)再次查找 BinarySearch(arr,leftIndex,midddle-1,findVal) }else if (*arr)[midddle] findVal{ //如果 arr[middle] findVal , 就应该向 middel1---- rightIndex BinarySearch(arr,midddle1,rightIndex,findVal) }else { //找到了 fmt.Printf(%v中找到元素%v,下标为%v\n,(*arr),findVal,midddle) } } func main() { ArraryNum : [6]int{1,8, 10, 89, 1000, 1234} ArraryNum2 : [6]int{8,200, 300, 889, 1000, 1234} BinarySearch(ArraryNum,0,len(ArraryNum),1234) BinarySearch(ArraryNum2,0,len(ArraryNum),300) BinarySearch(ArraryNum,0,len(ArraryNum),-8) BinarySearch(ArraryNum2,0,len(ArraryNum),30) }[1 8 10 89 1000 1234]中找到元素1234,下标为5[8 200 300 889 1000 1234]中找到元素300,下标为2[1 8 10 89 1000 1234]中找不到 元素-8[8 200 300 889 1000 1234]中找不到 元素30//**反转单链表1//反转链表的golang实现输入: 1-2-3-4-5-NULL输出: 5-4-3-2-1-NULLpackage main import fmt //链表节点 type ListNode struct { Val int Next *ListNode } //反转链表的实现 func reversrList(head *ListNode) *ListNode { cur : head var pre *ListNode nil for cur ! nil { pre, cur, cur.Next cur, cur.Next, pre //这句话最重要 } return pre } func main() { head : new(ListNode) head.Val 1 ln2 : new(ListNode) ln2.Val 2 ln3 : new(ListNode) ln3.Val 3 ln4 : new(ListNode) ln4.Val 4 ln5 : new(ListNode) ln5.Val 5 head.Next ln2 ln2.Next ln3 ln3.Next ln4 ln4.Next ln5 pre : reversrList(head) fmt.Println(pre) }查找不重复最长字串package main import fmt func lengthOfNonRepeatingSubStr(s string) int { lastMake : make(map[rune]int) start : 0 maxLength : 0 for i, ch : range []rune(s) { if lastI, ok : lastMake[ch]; ok lastI start { start lastMake[ch] 1 } if i-start1 maxLength { maxLength i - start 1 } lastMake[ch] i } return maxLength } func main() { fmt.Println(lengthOfNonRepeatingSubStr(abcabcbb)) fmt.Println(lengthOfNonRepeatingSubStr(bbbbb)) fmt.Println(lengthOfNonRepeatingSubStr(黑化肥发黑会挥发)) }大整数加法func stringReverse(str string) string { r : []rune(str) for i, j : 0, len(r)-1; i j; i, j i1, j-1 { r[i], r[j] r[j], r[i] } return string(r) } func add(str1 string, str2 string) string { if len(str1) len(str2) { str1 strings.Repeat(0, len(str2)-len(str1)) str1 } else if len(str1) len(str2) { str2 strings.Repeat(0, len(str1)-len(str2)) str2 } str1 stringReverse(str1) str2 stringReverse(str2) count : len(str1) nums : make([]byte, count) carry : false for i : 0; i count; i { sum : str1[i] - 0 str2[i] - 0 if carry { sum } if sum 9 { sum sum - 10 carry true } else { carry false } nums[i] sum 0 } result : stringReverse(string(nums)) if carry { result 1 result } return result }两个数组求交集思路把两个数组合并成一个数组然后通过 hash 表找出数组中重复的元素package main import fmt func ArrayIntersection(arr []int,arr1 []int)[]int{ var intersection []int arrappend(arr,arr1...) lastMake :make(map[int]int) for _,v:range arr{ if lastMake [v]1{ intersectionappend(intersection,v) }else{ lastMake [v]1 } } return intersection } func main() { arr1 : []int{1, 2, 3, 4, 5, 6} arr2 : []int{5, 6, 7, 8, 9, 0} fmt.Println(ArrayIntersection(arr1, arr2)) }字符串反转package main func Reverse(s string) string { r : []rune(s) for i, j : 0, len(r)-1; i j; i, j i1, j-1 { r[i], r[j] r[j], r[i] } return string(r) } func main() { a : Hello, 世界 println(a) println(Reverse(a)) }//*闭包func AddUpper() func(int) int {var n int 10return func(x int) int {n n xreturn n}}func main(){f : AddUpper()fmt.Println(f(1)) //11fmt.Println(f(2)) //13fmt.Println(f(3)) //16}编写Golang程序以查找给定数组中的重复元素例子输入数组 [1、3、5、6、1] 重复元素为1输入数组 [1、3、5、6、7] 返回-1解决这个问题的方法步骤1定义一个接受数组的方法。第2步声明访问过的映射。步骤3迭代给定的数组。如果该元素存在于已访问映射中则返回该元素。步骤4否则返回-1。package main import fmt func duplicateInArray(arr []int) int{ lastMake : make(map[int]bool, 0) for i:0; ilen(arr); i{ if lastMake [arr[i]] true{ return arr[i] } else { lastMake [arr[i]] true } } return -1 } func main(){ fmt.Println(duplicateInArray([]int{1, 4, 7, 2, 2})) fmt.Println(duplicateInArray([]int{1, 4, 7, 2, 3})) } 输出结果 2 -1Go语言数组中重复的数据题目给定一个题目给定一个整数数组 a 其中 1 a[i] n (n为数组长度)其中有些元素出现 两次 而其他元素出现 一次 。找到所有出现 两次 的元素。你可以不用任何额外空间并在 O(n) 时间复杂度内解决这个问题吗示例输入 [ 4, 3, 2, 7, 8, 2, 3, 1 ]输出 [ 2, 3 ]解法一使用 map 。用 map 中的 key 值存储数组中的每个元素value 存储其对应出现次数。最后输出 value 值为 2 的 key 即可。package main import fmt func main() { fmt.Println(findDuplicates([]int{1, 4, 7, 2, 2,1,7,8,9,3})) } func findDuplicates(arr []int) []int { lastMake : make(map[int]bool,1) var res []int for i:0;ilen(arr);i{ if lastMake[arr[i]]true{ resappend(res,arr[i]) }else{ lastMake[arr[i]]true } } return res }func findDuplicates(nums []int) []int { var lastMake map[int]int lastMake make(map[int]int) var i int for i 0; i len(nums); i { lastMake [nums[i]] } var res []int for key, value : range lastMake { if value 2 { res append(res, key) } } return res }解法三利用索引号巧妙进行哈希利用索引号巧妙进行func getAbs(num int) int { if num 0 { return num } return -num } func findDuplicates(nums []int) []int { var i int var res []int for i 0; i len(nums); i { index : getAbs(nums[i]) - 1 //获取数值nums[i]对应的下标index if nums[index] 0 { //如果nums[index]为负数表示nums[i]曾经出现过 res append(res, getAbs(nums[i])) } nums[index] -nums[index] //访问一次变为相反数作为标记 } return res }//栈//使用数组来模拟一个栈的使用。type Stack struct{MaxTop int //表示我们栈最大可以存放数个数Top int //表示栈顶因为栈顶固定因此我们直接使用Toparr [5]int //数组模拟栈}//入栈func (this *Stack) Push(val int) (err error){//先判断栈是否满了if this.Top this.MaxTop -1 {fmt.Println(stack full)return errors.New(stack full)}this.Top//放入数据this.arr[this.Top] val}//出栈func (this *Stack) Pop() (val int,err error){//判断栈是否空if this.Top -1 {fmt.Println(stack mepty!)return 0,errors.New(stack empty)}//先取值再 this.Top--var this.arr[this.Top]this.Top--return val,nil}//遍历栈,从栈顶开始遍历func (this *Stack) List(){//判断栈是否空if this.Top -1{fmt.Println(stack empty)return}//curTop : this.Topfor i : this.Top; i0; i-- {fmt.Println(arr[%d]%d\n,i,this.arr[i])}}func main(){stack : Stack{MaxTop : 5,Top : -1,}//入栈stack.Push(1)stack.Push(2)stack.Push(3)stack.Push(4)stack.Push(5)//显示stack.List() val,_ : stack.Pop()fmt.Println(出栈,val)stack.List()}//错误处理func test(){//使用defer recover 来捕获和处理异常defer func(){err : recover() // recover() 捕获异常if err ! nil{fmt.Println(err,err)}}()num1 : 10num2 : 20res : num1 /num2fmt.println(res,res)}func main(){test()for{fmt.Println()time.Sleep(time.Second)}}//斐波那契func fbn(n int) ([]uint64){fbnSlice : make([]uint64,n)fbnSlice[0]1fbnSlice[1]1for i : 2; in; i {fbnSlice[i] fbnSlice[i - 1] fbnSlice[i-2]}return fbnSlice}func main(){fnbSlice : fbn(10)fmt.Println(fnbSlice,fnbSlice)}package main import fmt //*二叉树 type Hero struct{ No int //编号 Name string Left *Hero //左边指针 Right *Hero //右边指针 } //前序 func PreOrder(node *Hero){ if node ! nil { fmt.Printf(no%d name%s\n,node.No,node.Name) PreOrder(node.Left) PreOrder(node.Right) } } //中序 func InfixOrder(node *Hero){ if node ! nil { InfixOrder(node.Left) fmt.Printf(no%d name%s\n,node.No,node.Name) InfixOrder(node.Right) } } //后序 func PostOrder(node *Hero){ if node ! nil { PostOrder(node.Left) PostOrder(node.Right) fmt.Printf(no%d name%s\n,node.No,node.Name) } } func main(){ root : Hero{ No : 1, Name : aa, } left1 : Hero{ No : 2, Name : bb, } node10 : Hero{ No : 10, Name : tom, } node12 : Hero{ No : 12, Name : tomA, } left1.Left node10 left1.Right node12 right1 : Hero{ No : 3, Name : cc, } root.Left left1 root.Right right1 right2 : Hero{ No : 4, Name : dd, } right1.Right right2 PreOrder(root) } /*结果 no1 nameaa no2 namebb no10 nametom no12 nametomA no3 namecc no4 namedd *///顺序查找names : [4]string{a,b,c,d,e,f}var heroName fmt.Scanln(heroName)for i : 0;ilen(names); i {if heroName names[i] {fmt.Printf(找到,heroName,i)break} else if i(len(names)-1) {fmt.Printf(没找到,heroName)}}//map排序map1 : make(map[int]int,10)map1[10] 100map1[1]13map1[4]56var keys []intfor k,_: range map1 {keys append(keys,k)}sort.Ints(keys)for _,k : range keys {fmt.Printf(map1[%v]%v \n,k,map1[k])}//**协程与管道//write Datafunc writeData(intChan chan int){for i : 1;i 50; i {//放入数据intChan- i}close(intChan)//关闭}//read datafunc readData(intChan chan int,exitChan chan bool){for {v,ok : -intChanif !ok {break}fmt.Printf(readData 读到数据%v\n,v)}//readData 读取完数据后任务完成exitChan- trueclose(exitChan)}func main(){//创那建两个管道intChan : make(chan int,50)exitChan : make(chan bool,1)go writeData(intChan)go readData(intChan,exitChan)for {_,ok : -exitChanif !ok {break}}}func main() {intChan : make(chan int, 20)exitChan : make(chan bool, 1)go func(intChan chan int){for i:0; i 20; i {intChan- (i%2 1)}close(intChan)}(intChan)go func(intChan chan int, exitChan chan bool) {for{v, ok : -intChanif ok {fmt.Println(v)}else{exitChan- trueclose(exitChan)break}}}(intChan, exitChan)for {_, ok : - exitChanif !ok {break}}}golang goroutine顺序循环打印ABCpackage main import fmt func main() { chan1,chan2,chan3,chan4:make(chan bool,1),make(chan bool,1),make(chan bool,1),make(chan bool,1) n:20 go func(){ for i:1;in;i3{ -chan1 fmt.Println(A) chan2-true } }() go func(){ for i:2;in;i3{ -chan2 fmt.Println(B) chan3-true } }() go func(){ for i:3;in;i3{ if i 3{ chan1 - true } -chan3 fmt.Println(C) chan1-true } chan4-true }() -chan4 } /** A B C A B C A B C **/2package main import fmt var chan1 make(chan bool, 1) var chan2 make(chan bool) var chan3 make(chan bool,1) var index make(chan bool, 1) func func1() { for i : 1;i10;i { -chan1 fmt.Println(A) chan2 - true } } func func2() { for i : 1;i10 ;i { -chan2 fmt.Println(B) chan3 - true } } func func3(){ for i : 1;i10 ;i { -chan3 fmt.Println(C) chan1- true } index-true } func main() { chan1 - true go func1() go func2() go func3() -index }go语言实现两个goroutine交替执行打印数字和字母,效果:12AB34CD56EF...go语言实现两个goroutine交替执行打印数字和字母,效果:12AB34CD56EF... - it610.comvar chan1 make(chan bool, 1) var chan2 make(chan bool) var index make(chan bool, 1) func func1() { for i : 1; i 26; i 2 { // 2, 取走chan1里的元素,继续运行,打印两个数字 -chan1 fmt.Print(i) fmt.Print(i 1) // 3, 给chan2 放入一个元素,等待取走元素 chan2 - true } } func func2() { for i : A; i Z; i 2 { // 4, chan2 取出元素,执行打印两个字符 , -chan2 fmt.Print(string(i)) fmt.Print(string(i1)) // 5, chan1 接收一个元素,进入阻塞状态,等待取走元素,进入第2步,2345步一直循环直到打印完 chan1 - true } // 6, 结束循环,index通道接收一个元素,进入阻塞状态,等待取走 index - true } func main() { // 1, chan1 里放一个值,进入阻塞状态,等待取走元素 chan1 - true go func1() go func2() // 7, index通道取走元素,继续往下执行 -index // 结果: 12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ }基于3个goroutine交替顺序打印自然数//1 package main import fmt func main() { chA,chB,chC,index:make(chan bool,1),make(chan bool,1),make(chan bool,1),make(chan bool,1) go func(){ for i:1;i20;i3{ -chA fmt.Println([A],i) chB-true } }() go func(){ for i:2;i20;i3{ -chB fmt.Println([B],i) chC-true } }() go func(){ for i:3;i20;i3{ if i3{ chA-true } -chC fmt.Println([C],i) chA-true } index-true }() -index }//2 func main() { chA, chB, chC : make(chan string), make(chan string), make(chan string) go func() { for i : 1; ; { select { case -chA: fmt.Println([A]:, i) chB - B i 3 } } }() go func() { for i : 2; ; { select { case -chB: fmt.Println([B]:, i) chC - C i 3 } } }() go func() { for i : 3; ; { if i 3 { chA - A } select { case -chC: fmt.Println([C]:, i) chA - A i 3 } } }() for !false { fmt.Print() } } 控制台 [A]: 1 [B]: 2 [C]: 3 [A]: 4 [B]: 5 [C]: 6 [A]: 7 [B]: 8 [C]: 9golang 两个协成交替打印1-100的奇数偶数package main import( fmt ) func groutine1(p chan int,e chan bool){ for i:1;i10;i{ p-i if i%21{ fmt.Println(groutine1:,i) } } e-true close(e) } func groutine2(p chan int,e chan bool){ for i:1;i10;i{ -p if i%20{ fmt.Println(groutine2:,i) } } e-true close(e) } func main(){ msg:make(chan int) e:make(chan bool,1) go groutine1(msg,e) go groutine2(msg,e) //time.Sleep(time.Second *1) for{ _,ok:-e if !ok{ break } } }package main import ( fmt time ) var POOL 100 func groutine1(p chan int) { for i : 1; i POOL; i { p - i if i%2 1 { fmt.Println(groutine-1:, i) } } } func groutine2(p chan int) { for i : 1; i POOL; i { -p if i%2 0 { fmt.Println(groutine-2:, i) } } } func main() { msg : make(chan int) go groutine1(msg) go groutine2(msg) time.Sleep(time.Second * 1) }groutine-1: 1groutine-2: 2groutine-1: 3groutine-2: 4groutine-1: 5groutine-2: 6groutine-1: 7groutine-2: 8//使用select可以解决从管道取数据的阻塞问题func main(){//使用select可以解决从管道取数据的阻塞问题// 1.定义一个管道 10个数据intChan : make(chan int,10)for i : 0; i10;i {intChan - i}// 2.定义一个管道 5个数据stringstringChan : make(chan string, 5)for i : 0; i 5; i {stringChan - hello fmt.Sprintf(%d,i)}label :for {//注意这里如果intChan一直没有关闭不会一直阻塞而deadlock//会自动到下一个case匹配select {case v : -intChan :fmt.Printf(从intChan读取的数据%d\n,v)case v : -stringChan :fmt.Printf(从stringChan读取的数据%s\n,v)default:fmt.Printf(都取不到了取的数据\n)//returnbreak label}}}var intArr3 [5]int//为了每次生成的随机数不一样我们需要给一个seed值rand.Seed(time.Now().UnixNano())for i : 0; i len(intArr3); i {intArr3[i] rand.Intn(100) //0n100}fmt.Println(交换前,intArr3)//反转打印交换的次数是 len / 2,//倒数第一个和第一个元素交换倒数第二个和第二个元素交换temp : 0for i : 0; i len(intArr3) / 2; i {temp intArr3[len(intArr3) - 1 - i]intArr3[len(intArr3) - 1 - i] intArr3[i]intArr3[i] temp}fmt.Println(交换后,intArr3)找出不重复最多字符串位数hello : abcabbacdaftgsyaci : 0jj : 0mp : make(map[int32]int32)for _,v : range hello{if _,ok : mp[v];!ok {mp[v]vci}else{mp make(map[int32]int32)mp[v]vif ci jj {jj ci}ci 1}}return ci请符合两数之和的索引给定一个整数数组和一个目标值找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案且同样的元素不能被重复利用。示例:给定nums [2, 7, 11, 15], target 9因为 nums[0] nums[1] 2 7 9所以返回 [0, 1]暴力破解法func twoSum(nums []int, target int) []int {length : len(nums)for i:0;ilength;i{for j:i1;jlength;j{if t : nums[i]nums[j];ttarget{return []int{i,j}}}}return []int{}}

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑