发布日期:2023-5-19 更新日期: 2023-5-19文章字数 0阅读时长:0分钟

type
status
date
slug
summary
tags
category
icon
password
😀
记录一下使用golang接触到的一些编程题

📝 主旨内容

双/三指针:

接雨水

接雨水问题是一个经典的算法问题,可以使用双指针或者单调栈来解决。下面给出使用双指针的解法:
假设有一个数组 heights 表示高度,那么我们可以从左右两边分别使用一对指针 left 和 right,用变量 leftMax 和 rightMax 记录左右两侧的最大高度。
然后我们不断地移动指针,如果当前指向的位置的高度小于等于 leftMax 或者 rightMax 中的最小值,那么这个位置上方能够接到的雨水高度就是 min(leftMax, rightMax) - height[i]。否则,如果当前位置的高度大于 leftMax 和 rightMax 的最小值,那么我们更新 leftMax 和 rightMax 中较小的那个值。
最终,我们将所有位置上方能够接到的雨水高度相加得到答案。
以下是 Golang 代码实现:
func trap(height []int) (ans int) { left, right, preMax, sufMax := 0, len(height)-1, 0, 0 for left <= right { preMax = max(preMax, height[left]) sufMax = max(sufMax, height[right]) if preMax < sufMax { ans += preMax - height[left] left++ } else { ans += sufMax - height[right] right-- } } return } func max(a, b int) int { if a < b { return b }; return a }

三数之和

func threeSum(nums []int) [][]int { res:=[][]int{} sort.Ints(nums) for i:=0;i<len(nums);i++{ n1 :=nums[i] if n1>0 { break } if i>0 && n1==nums[i-1]{ continue } l,r:=i+1,len(nums)-1 for l<r{ n2,n3:=nums[l],nums[r] if n1+n2+n3==0 { res=append(res,[]int{n1,n2,n3}) for nums[l]==n2 && l<r{ l++ } for nums[r]==n3 && l<r{ r-- } }else if n1+n2+n3>0{ r-- }else { l++ } } } return res }
notion image
 
 

二分:

装水的最大容器

func maxArea(height []int) int { res,left,right :=0,0,len(height)-1 for left<right{ width :=right-left high :=0 if height[left]<height[right] { high = height[left] left++ }else{ high = height[right] right-- } sum :=width*high res = max(res,sum) } return res } func max(i,j int) int { if i>j { return i } return j }
 
 

哈希表:

无重复字符串最长子串

func lengthOfLongestSubstring(s string) int { /** 思路分析: 不重复连续的一段字符串,这段必然是整体的一部分。所以这里可以用滑动窗口。试想比如asdfgd,针对上面这个,我们开始先把元素加到map中,每次比较map里没有就加入,比如现在是 asdfg了,现在看下一个d存在了,所以这个d加不进去了,右窗口也无法移动,这时候右不动,左动。一直到左不动右动。当左边把d移走,右边的d就能进来了,这样最终就能把最大的取到。 **/ //开始 //先循环主体 n := len(s) var memory = make(map[byte]int, n) maxSize := 0 //定义左右窗口,定义右为-1,左为0。因为右边每次要加+,又要把第一个加进来,所以直接-1开始 j := 0 for i:=0; i<n; i++ { if i > 0 { //当右不动左才动,所以左动要移出,右动要加入 delete(memory, s[i-1]) } //右动,因为窗口长度是右-左,所以这个j是一不会重置的变量 //memory没有才加入 for j < n && memory[s[j]] == 0 { memory[s[j]] = 1 j++//右移 } //每一次选出最大的,此时右边是j+1,左边是i maxSize = max(maxSize, len(memory)) } return maxSize } func max(a, b int) int { if a > b { return a } return b }

最长无重复子数组

package main /** * * @param arr int整型一维数组 the array * @return int整型 */ func maxLength( arr []int ) int { // write code here res,hmap := 0,make(map[int]int) for i,j:=0,0;j<len(arr);j++{ if index,ok:=hmap[arr[j]];ok{ i=max(index+1,i) } hmap[arr[j]]=j res = max(j-i+1,res) } return res } func max(i,j int) int{ if i>j{ return i } return j }

最长连续序列

func longestConsecutive(nums []int) int { numSet := map[int]bool{} for _,num := range nums{ numSet[num] = true } longestStreak := 0 for num := range numSet{ if !numSet[num-1]{ currentNum := num currentStreak := 1 for numSet[currentNum+1]{ currentNum++ currentStreak++ } if longestStreak<currentStreak{ longestStreak=currentStreak } } } return longestStreak }

两数之和

func twoSum(nums []int, target int) []int { cache := map[int]int{} for i:=0;i<len(nums);i++ { if v,ok := cache[target-nums[i]]; ok{ return []int{v,i} } cache[nums[i]]=i } return []int{} }

数组只出现一次的的数字

func firstUniqChar(s string) byte { cnt := [26]int{} for _, ch := range s { cnt[ch-'a']++ } for i, ch := range s { if cnt[ch-'a'] == 1 { return s[i] } } return ' ' }
 

DP:

最长公共子串

package main /** * longest common substring * @param str1 string字符串 the string * @param str2 string字符串 the string * @return string字符串 */ func LCS(str1 string, str2 string) string { // write code here l1 := len(str1) //行 l2 := len(str2) // 列 if l1 == 0 || l2 == 0 { return "" } // 第一行 第一列都为空 // 主要是为了好处理 dp[0][0] dp := make([][]int, l1+1) for i := 0; i < l1+1; i++ { dp[i] = make([]int, l2+1) } max := 0 end := 0 // 注意 l1+1 l2+1 // 二维数组dp[i][j]表示第一个字符串前i个字符和第二个字符串前j个字符组成的最长公共字符串的长度 // 字符相等 dp[i][j] = dp[i-1][j-1] + 1 否则 dp[i][j] = 0 for i := 1; i < l1+1; i++ { for j := 1; j < l2+1; j++ { if str1[i-1] == str2[j-1] { dp[i][j] = dp[i-1][j-1] + 1 } else { dp[i][j] = 0 } if dp[i][j] > max { max = dp[i][j] end = i // 注意 } } } if max == 0 { return "" } return str1[end-max : end] }
notion image

力扣45.跳跃游戏II

func jump(nums []int) int { dp:=make([]int ,len(nums)) dp[0]=0 for i:=1;i<len(nums);i++{ dp[i]=i for j:=0;j<i;j++{ if nums[j]+j>i{ dp[i]=min(dp[j]+1,dp[i]) } } } return dp[len(nums)-1] }

斐波那契数列

package main //动态规划,时间On func Fibonacci( n int ) int { if n <= 1 { return n } dp := make([]int, n+1) dp[1], dp[2] = 1, 1 for i := 2; i <= n; i++ { dp[i] = dp[i-1] + dp[i-2] } return dp[n] } /* //状态压缩,空间O1 func Fibonacci( n int ) int { if n <= 2 { return 1 } temp := 0 a, b := 1, 1 for i := 2; i < n; i++ { temp = a + b a = b b = temp } return temp } */

买卖股票的最佳时机

func maxProfit(prices []int) int { n:=len(prices) if n==0{ return 0 } dp:=make([][]int,n) for i:=0;i<n;i++{ dp[i] = make([]int,2) } dp[0][0]=-prices[0] dp[0][1]=0 for i:=1;i<n;i++{ dp[i][0] = max(-prices[i],dp[i-1][0]) dp[i][1] = max(prices[i]+dp[i-1][0],dp[i-1][1]) } return dp[n-1][1] } func max(a,b int) int { if a > b {return a} return b }
 
 

排序:

快速排序

package main import ( "fmt" ) // 快速排序 // 说明 // 1 left 表示数组左边的下标 // 2 right 表示数组右边的下标 // 3 array 表示要排序的数组 func QuickSort(left int, right int, array *[9]int) { l := left r := right // pivot 是中轴, 支点 pivot := array[(left+right)/2] temp := 0 // for 循环的目标是将比 pivot 小的数放到左边,比 pivot 大的数放到右边 for l < r { // 从 pivot 的左边找到大于等于pivot的值 for array[l] < pivot { l++ } // 从 pivot 的右边边找到小于等于pivot的值 for array[r] > pivot { r-- } // 1 >= r 表明本次分解任务完成, break if l >= r { break } // 交换 temp = array[l] array[l] = array[r] array[r] = temp // 优化 if array[l] == pivot { r-- } if array[r] == pivot { l++ } } // 如果 1== r, 再移动下 if l == r { l++ r-- } // 向左递归 if left < r { QuickSort(left, r, array) } // 向右递归 if right > l { QuickSort(l, right, array) } } func main() { arr := [9]int{-9, 78, 0, 23, -567, 70, 123, 90, -23} / /调用快速排序 QuickSort(0, len(arr)-1, &arr) fmt.Println(arr) }

归并排序

func mergeSort(nums []int) []int { length := len(nums) if length < 2 { return nums } left := nums[:length/2] right := nums[length/2:] return merge(mergeSort(left), mergeSort(right)) } func merge(left, right []int) []int { var res []int for len(left) != 0 && len(right) != 0 { if left[0] <= right[0] { res = append(res, left[0]) left = left[1:] } else { res = append(res, right[0]) right = right[1:] } } for len(left) != 0 { res = append(res, left[0]) left = left[1:] } for len(right) != 0 { res = append(res, right[0]) right = right[1:] } return res }
notion image
 
 
 
 
 

链表:

k个一组反转链表

func reverseKGroup(head *ListNode, k int) *ListNode { if head == nil || k <= 1 { return head } count := 0 cur := head // 统计当前链表长度 for count < k && cur != nil { cur = cur.Next count++ } // 如果当前链表长度不足 K 个,直接返回 if count < k { return head } // 翻转前 K 个节点 newHead := reverseList(head, cur) // 递归处理后续子链表 head.Next = reverseKGroup(cur, k) return newHead } // 翻转链表 func reverseList(head, tail *ListNode) *ListNode { var prev *ListNode = nil curr := head for curr != tail { next := curr.Next curr.Next = prev prev = curr curr = next } return prev }

从尾到头打印链表

// ListNode represents a node in a linked list type ListNode struct { Val int Next *ListNode } // printListFromTailToHead 逆序打印链表 func printListFromTailToHead(listNode *ListNode) []int { num := []int{} for listNode != nil { num = append(num, listNode.Val) listNode = listNode.Next } // 逆序输出 res := []int{} for i := len(num) - 1; i >= 0; i-- { res = append(res, num[i]) } return res }

反转链表

type ListNode struct { Val int Next *ListNode } func ReverseList(head *ListNode) *ListNode { if head == nil { return nil } var pre *ListNode for head != nil { next := head.Next head.Next = pre pre = head head = next } return pre }

合并两个排序的链表

// ListNode represents a node in a linked list type ListNode struct { Val int Next *ListNode } // Merge 合并两个有序链表 func Merge(list1, list2 *ListNode) *ListNode { if list1 == nil { return list2 } if list2 == nil { return list1 } if list1.Val <= list2.Val { list1.Next = Merge(list1.Next, list2) return list1 } list2.Next = Merge(list1, list2.Next) return list2 }

两个链表的第一个公共结点

type ListNode struct { Val int Next *ListNode } func FindFirstCommonNode(pHead1, pHead2 *ListNode) *ListNode { set := make(map[*ListNode]bool) if pHead1 == nil || pHead2 == nil { return nil } for pHead1 != nil { set[pHead1] = true pHead1 = pHead1.Next } for pHead2 != nil { if set[pHead2] { return pHead2 } pHead2 = pHead2.Next } return nil }

链表中环的入口结点

type ListNode struct { Val int Next *ListNode } func EntryNodeOfLoop(pHead *ListNode) *ListNode { set := make(map[*ListNode]bool) for pHead != nil { if set[pHead] { return pHead } set[pHead] = true pHead = pHead.Next } return nil }

链表中倒数最后k个结点

type ListNode struct { Val int Next *ListNode } func FindKthToTail(pHead *ListNode, k int) *ListNode { if pHead == nil || k == 0 { return nil } var count int temp := pHead for temp != nil {

复杂链表的复制

type RandomListNode struct { Label int Next *RandomListNode Random *RandomListNode } func Clone(pHead *RandomListNode) *RandomListNode { cachedNode := make(map[*RandomListNode]*RandomListNode) if pHead == nil { return nil } if _, ok := cachedNode[pHead]; !ok { headNew := &RandomListNode{ Label: pHead.Label, } cachedNode[pHead] = headNew headNew.Next = Clone(pHead.Next) headNew.Random = Clone(pHead.Random) } return cachedNode[pHead] }

删除链表中重复的结点

type ListNode struct { Val int Next *ListNode } func deleteDuplication(pHead *ListNode) *ListNode { if pHead == nil || pHead.Next == nil { return pHead } if pHead.Val == pHead.Next.Val { pNode := pHead.Next for pNode != nil && pNode.Val == pHead.Val { pNode = pNode.Next } return deleteDuplication(pNode) } else { pHead.Next = deleteDuplication(pHead.Next) return pHead } }
 

DFS:

八皇后

package main import "fmt" var res [8]int //存储结果 //判断当前位置是否合法 func isValid(row, col int) bool { for i := 0; i < row; i++ { if res[i] == col || row-i == abs(res[i]-col) { //row-i == abs(res[i]-col) 判断当前位置是否在左上角和右上角两个方向上与已经放置好的皇后冲突。具体来说 //res[i] == col 判断当前位置所在的列是否已经有皇后 return false } } return true } //打印结果 func printRes() { for i := 0; i < 8; i++ { for j := 0; j < 8; j++ { if res[i] == j { fmt.Print("Q ") } else { fmt.Print(". ") } } fmt.Println() } fmt.Println("===================") } //回溯求解 func backtrack(row int) { if row == 8 { //如果已经找到合法解 printRes() //输出结果 return } for col := 0; col < 8; col++ { //枚举所有列 if isValid(row, col) { //如果当前位置合法 res[row] = col //记录当前位置 backtrack(row + 1) //递归下一行 } } } func abs(x int) int { if x < 0 { return -x } return x } func main() { backtrack(0) //从第0行开始回溯 }
 

队列:

两个数组实现队列

package main var stack1 [] int var stack2 [] int func Push(node int) {     stack1 = append(stack1,node) } func Pop() int{     if len(stack2) !=0 {         tmp := stack2[len(stack2)-1]         stack2 = stack2[:len(stack2)-1]         return  tmp     }     if len(stack1) != 0 {         tmp := stack1[0]         for i:=len(stack1)-1;i>0;i-- {             stack2 = append(stack2,stack1[i])         }         stack1=[]int{}         return  tmp     }     return -1 }
notion image

回溯:

回朔,全排列,无重复数字的

package main /** * * @param num int整型一维数组 * @return int整型二维数组 */ var res [][]int func permute( num []int ) [][]int { // write code here res = [][]int{} hs(num,0) return res } func hs(num []int,v int){ if v == len(num) { temp := make([]int,len(num)) copy(temp,num) res =append(res,temp) return } for i:=v;i<len(num);i++{ num[i],num[v] =num[v],num[i] hs(num,v+1) num[i],num[v] =num[v],num[i] } }

有重复数组

func permuteUnique(num []int) [][]int { sort.Ints(num) size := len(num) resArr := make([][]int, 0) tmp := make([]int, 0) isVisited := make([]bool, size) var dfs func(start int) dfs = func(start int) { if start == size { resArr = append(resArr, append([]int(nil), tmp...)) return } for i, val := range num { //从左至右剔除重复的元素 if isVisited[i] || (i > 0 && !isVisited[i-1] && val == num[i-1]) { continue } tmp = append(tmp, val) isVisited[i] = true dfs(start + 1) tmp = tmp[:len(tmp)-1] isVisited[i] = false } } dfs(0) return resArr }
 
 
 
 

树:

两个节点的最近公共祖先

package main import . "nc_tools" /* * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ /** * * @param root TreeNode类 * @param o1 int整型 * @param o2 int整型 * @return int整型 */ func isParent(root *TreeNode,o1,o2 int) *TreeNode{ if root == nil || root.Val == o1 || root.Val == o2{ return root } left := isParent(root.Left,o1,o2) right := isParent(root.Right,o1,o2) if left == nil{ return right } if right == nil{ return left } return root } func lowestCommonAncestor( root *TreeNode , o1 int , o2 int ) int { if root ==nil{ return -1 } res:= isParent(root,o1,o2) if res == nil{ return -1 } return res.Val }
💡
思路:遍历子节点,遍历到对应节点就返回,因为此时二个节点是父子关系。
遍历子节点,左子树没找到,则返回右子树,右子树找不到,就返回左子树。
两者都找到了,则返回root,因为此时的root是公共父节点。
 
 

二叉树的深度

package main func TreeDepth(TreeNode root) int{ if root == null{ return 0; } return max(TreeDepth(root.Left),TreeDepth(root.Right)) +1 } func max(i,j int) int{ if i>j{ return i } return j }

按之字形顺序打印二叉树

type TreeNode struct { Val int Left *TreeNode Right *TreeNode } // PrintTreeByZigzag 递归实现按之字形顺序打印二叉树 func PrintTreeByZigzag(root *TreeNode) { if root == nil { return } // 定义两个栈,分别存储当前层和下一层的节点 currentStack := []*TreeNode{root} nextStack := []*TreeNode{} // 定义一个变量表示当前打印的是从左到右还是从右到左 fromLeft := true for len(currentStack) > 0 { // 取出当前层的第一个节点 node := currentStack[0] currentStack = currentStack[1:] // 打印当前节点 fmt.Print(node.Val, " ") // 把当前节点的左右子节点压入下一层的栈中 if fromLeft { if node.Left != nil { nextStack = append(nextStack, node.Left) } if node.Right != nil { nextStack = append(nextStack, node.Right) } } else { if node.Right != nil { nextStack = append(nextStack, node.Right) } if node.Left != nil { nextStack = append(nextStack, node.Left) } } // 如果当前层的节点已经全部打印完毕,交换当前层和下一层的栈,并更改打印顺序 if len(currentStack) == 0 { currentStack, nextStack = nextStack, currentStack fromLeft = !fromLeft } } }

二叉搜索树的第k个结点

func KthNode(pRoot *TreeNode, k int) *TreeNode { if pRoot == nil || k <= 0 { return nil } stack := []*TreeNode{} cur := pRoot for len(stack) > 0 || cur != nil { for cur != nil { stack = append(stack, cur) cur = cur.Left } cur = stack[len(stack)-1] stack = stack[:len(stack)-1] if k == 1 { return cur } k-- cur = cur.Right } return nil }

重建二叉树

// TreeNode represents a node in a binary tree type TreeNode struct { Val int Left *TreeNode Right *TreeNode } // reConstructBinaryTree 重建二叉树 func reConstructBinaryTree(pre, vin []int) *TreeNode { // 构造 HashMap hashmap := make(map[int]int) for i := 0; i < len(vin); i++ { hashmap[vin[i]] = i } return recur(pre, 0, 0, len(pre)-1, hashmap) } // recur 递归构造二叉树 func recur(pre []int, root, left, right int, hashmap map[int]int) *TreeNode { if left > right { return nil } // 构造当前结点 node := &TreeNode{ Val: pre[root], } cur := hashmap[pre[root]] // 递归构造左子树 node.Left = recur(pre, root+1, left, cur-1, hashmap) // 递归构造右子树 node.Right = recur(pre, root+1+cur-left, cur+1, right, hashmap) return node }
方法二:
// TreeNode represents a node in a binary tree type TreeNode struct { Val int Left *TreeNode Right *TreeNode } // buildTree 重建二叉树 func buildTree(preorder, inorder []int) *TreeNode { // 构造 HashMap hashmap := make(map[int]int) n := len(inorder) for i := 0; i < n; i++ { hashmap[inorder[i]] = i } return recur(preorder, 0, n-1, 0, n-1, hashmap) } // recur 递归构造二叉树 func recur(preorder []int, preLeft, preRight, inoLeft, inoRight int, hashmap map[int]int) *TreeNode { if preLeft > preRight { return nil } // 构造当前结点 preRoot := preLeft inoRoot := hashmap[preorder[preRoot]] root := &TreeNode{ Val: preorder[preRoot], } size := inoRoot - inoLeft // 递归构造左子树 root.Left = recur(preorder, preRoot+1, preRoot+size, inoLeft, inoRoot-1, hashmap) // 递归构造右子树 root.Right = recur(preorder, preRoot+size+1, preRight, inoRoot+1, inoRight, hashmap) return root }

树的子结构

二叉树的镜像

从上往下打印二叉树

二叉搜索树的后序遍历序列

二叉树中和为某一值的路径

二叉搜索树与双向链表

平衡二叉树

二叉树的下一个结点

对称的二叉树

把二叉树打印成多行

序列化二叉树

 

堆:

第 k 个最大的元素

type IntHeap []int func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *IntHeap) Push(x interface{}) { *h = append(*h, x.(int)) } func (h *IntHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } func findKthLargest(nums []int, k int) int { h := (*IntHeap)(unsafe.Pointer(&nums)) heap.Init(h) for h.Len()!= k { heap.Pop(h) } return heap.Pop(h).(int) }
 
 

其他:

大数相加

package main import "strconv" /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算两个数之和 * @param s string字符串 表示第一个整数 * @param t string字符串 表示第二个整数 * @return string字符串 */ func solve( s string , t string ) string { // write code here tmp,n,m:=0,len(s)-1,len(t)-1 result := "" for n>=0 || m >=0 || tmp!=0{ i,j := 0,0 if n>=0{ i = int(s[n]-'0') n-- } if m>=0{ j = int(t[m]-'0') m-- } tmp += i+j result = strconv.Itoa(tmp %10)+result tmp /=10 } return result }

结构体排序

package main import ( "fmt" "sort" ) // 学生信息 type Student struct { Age int Score int } // 结构体数组 type Students []*Student // 下面的三个函数必须实现(获取长度函数,交换函数,比较函数(这里比较的是年龄)) func (s Students) Len() int { return len(s) } func (s Students) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s Students) Less(i, j int) bool { return s[i].Age < s[j].Age } func main() { // 新建3个学生信息,这里特意用指针,表示指针也没问题;当然直接用结构体也是可以的 Data := []*Student{} Data = append(Data, &Student{Age: 10, Score: 100}) Data = append(Data, &Student{Age: 9, Score: 90}) Data = append(Data, &Student{Age: 11, Score: 110}) sort.Sort(sort.Reverse(Students(Data))) fmt.Printf("根据年龄从大到小排序 \\n") for i := 0; i < len(Data); i++ { fmt.Printf("第%v个学生%+v \\n", i, Data[i]) } sort.Sort(Students(Data)) fmt.Printf("\\n根据年龄从小到大排序 \\n") for i := 0; i < len(Data); i++ { fmt.Printf("第%v个学生%+v \\n", i, Data[i]) } }

最长公共子序列

func canJump(nums int[]) { n := nums.length; rightMost := 0; for(i := 0; i < n; i++){ if(i <= rightMost){ rightMost = math.Max(rightMost, i + nums[i]); if(rightMost >= n - 1){ return true; } } } return false; }

合并两个有序的数组

func merge( A []int , m int, B []int, n int ) { // write code here if len(A)==0 &&len(B)==0{ return } // 从后往前两两比较,大的赋值 for m!=0&&n!=0{ if A[m-1]<B[n-1]{ A[m+n-1] = B[n-1] // 大的赋值 n-- // 指针移动 }else { A[m+n-1] = A[m-1] m-- } } // 只考虑B数组剩余的情况,也就是n指针,因为A数组是整合后的数组 for n>0 { A[n-1]=B[n-1] n-- } }

反转数字

func reverse(x int) int { rev := 0 for x != 0 { if rev < math.MinInt32/10 || rev > math.MaxInt32/10 { return 0 } digit := x % 10 x /= 10 rev = rev*10 + digit } return rev }

数组中出现次数超过一半的数字

func majorityElement(nums []int) int { vote,now:=1,nums[0] for i:=1;i<len(nums);i++{ if vote==0{ now=nums[i] } if nums[i]==now{ vote++ }else{ vote-- } } return now }
 

数字转ip

package main import ( "fmt" ) func intToIP(ipInt uint32) string { return fmt.Sprintf("%d.%d.%d.%d", byte(ipInt>>24), byte(ipInt>>16), byte(ipInt>>8), byte(ipInt)) } func main() { ipInt := uint32(3232235777) // 192.168.1.1 的整数表示 ip := intToIP(ipInt) fmt.Println(ip) // 输出: 192.168.1.1 }
 

多生产者多消费者

package main import ( "fmt" "sync" ) var wg sync.WaitGroup func Provider(data chan<- int,name string){ for i:=0;i<40;i++{ //保证传入i的操作和print操作"原子运行" select { case data<-i: fmt.Println(name,"生产了:",i) } } wg.Done() } func Consumer(data <-chan int,name string){ for i:=0;i<40;i++ { fmt.Println(name,"读取了",<-data) } wg.Done() } func main() { //定义缓冲区大小 data:=make(chan int,10) wg.Add(6) go Provider(data,"p1") go Provider(data,"p2") go Provider(data,"p3") go Consumer(data,"c1") go Consumer(data,"c2") go Consumer(data,"c3") wg.Wait() }
 

golang协程交替打印

package main import ( "fmt" "sync" ) func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() for i := 1; i < 101; i++ { ch <- 0 if i%2 == 1 { fmt.Println("线程1打印:", i) } } }() go func() { defer wg.Done() for i := 1; i < 101; i++ { <-ch if i%2 == 0 { fmt.Println("线程2打印:", i) } } }() wg.Wait() }

go协程交替打印奇数偶数

package main import ( "fmt" ) func main() { ch := make(chan int) exit := make(chan int) go func() { // 如果channel中没有数据,<-ch阻塞,直到channel中有一个数据时,取出channel的数据并判断i的值是否是偶数,如果是偶数,则打印 for i := 1; i < 10; i += 1 { <-ch if i%2 == 0 { fmt.Println(i) } } }() // 第一次循环时,channel为空,可以向channel写入数据,此时i=1,所以,可以打印出1 // 第二次循环时,channel不为空,所以 ch <- 0语句阻塞,直到channel内没有数据 go func() { for i := 1; i < 10; i += 1 { ch <- 0 if i%2 == 1 { fmt.Println(i) } } exit <- 0 }() <-exit }
 
 
 
 

🤗 总结归纳

💡
记录一下使用golang接触到的一些编程题
尚未写的题目:
NC24 删除有序链表中重复出现的元素
NC54数组中相加和为0的三元组 NC41找到字符串的最长无重复字符子串 NC74数字在升序数组中出现的次数 NC119最小的K个数 NC92最长公共子序列 NC66两个链表的第一个公共结点 NC30数组中未出现的最小正整数 比较版本号

Golang通用题解模板 Golang通用题解模板

记录Golang通用的编程题解答模板


算法与数据结构 算法与数据结构

本文记载一些算法与数据结构


公告
type
status
date
slug
summary
tags
category
icon
password
🎉欢迎来到我的博客🎉
关于我
notion image
Khaos,后端工程师,喜欢高效学习、喜欢电吉他、喜欢敲代码。
写作是为了记录自己的技术,同时倒逼自己学习。
与我联系
👏欢迎与我交流👏
QQ:992308975
公众号:程序员khaos
QQ群:648726870