Go语言刷LeetCode

最近在学go语言,为了迅速上手而采用刷leetcode的方法,在这之前刷leetcode使用的语言是java
使用的go语言版本是1.19.2

项目结构和配置

在学go之前,使用java刷leetcode。为了调试方便在自己本地建了一个目录存放代码,然后使用vscode敲代码。由于java每一个class文件都可以包含main方法,调试起来很方便。但是go语言中一个包不能有多个main函数,如果需要多个main函数需要独立建包,很麻烦
大概结构如下:

  • Java
    题目1.java
    题目2.java
    题目3.java
  • GO
    题目1包
    |---- 题目1.go
    题目2包
    |---- 题目2.go
    题目3包
    |---- 题目3.go

这个时候我盯上了go语言中的单元测试模块。单元测试模块只有两个要求

  1. go文件名以 _test结尾
  2. 测试函数以Test开头,入参 *testing.T
    在vscode里面会自动识别并跳出run test 和debug test的按钮来运行和调试
    在这里插入图片描述
    当然也可以右击函数,选择生成对应的测试函数
    在这里插入图片描述
    go test默认不打印变量,需要在文件>>首选项>>设置>>工作区设置,搜索go后进入对应的setting.json,设置go.testFlags。其中-v表示显示打印信息,-timeout是设置超时,防止永久循环现象。
{
    "go.testFlags": [
        "-v",
        "-timeout=300ms"
    ],
}

输入转换

leetcode中的输入通常使用json形式,为了转换需要使用go自带的json库 “encoding/json”。以输入2维数组为例,代码如下:

func ConstructInt2DArray(jsonInput string) [][]int {
	var str2dArray [][]int
	if err := json.Unmarshal([]byte(jsonInput), &str2dArray); err != nil {
		log.Fatal(err)
	}
	return str2dArray
}

对于一些数据结构来说,json的转换还不够,需要进一步的转化,比如链表、树。这一步本身也是训练自己代码能力的步骤。以链表为例

func ConstructListNode(jsonListNode string) *ListNode {
	sliceInt := ConstructIntArray(jsonListNode)
	head := new(ListNode)
	node := head
	for _, val := range sliceInt {
		node.Next = new(ListNode)
		node.Next.Val = val
		node = node.Next
	}
	return head.Next
}

输出转换

为了方便调试,对一些数据结构的输出需要进行一定的处理。这里为链表制作了一个转字符串的函数。

func ListNode2String(root *ListNode) string {
	var builder strings.Builder
	node := root
	builder.WriteString("[")
	for {
		builder.WriteString(strconv.Itoa(node.Val))
		node = node.Next
		if node != nil {
			builder.WriteString(",")
		} else {
			break
		}
	}
	builder.WriteString("]")
	return builder.String()
}

工具

max、min

不同于java,go语言缺少了很多方便的工具类,比如max函数,go语言只提供了math(float,float)的函数,对于整数并不支持。需要自己处理,以max为例,这里制作了一个任意长度输入的max函数:

func max(nums ...int) int {
	max := nums[0]
	for i := 1; i < len(nums); i++ {
		if nums[i] > max {
			max = nums[i]
		}
	}
	return max
}

栈和队列

考虑到go语言在1.8以后支持泛型,为了保持java转过来的习惯,我用泛型写了部分队列、栈的操作。但是leetcode的编译器貌似并不支持泛型,于是放弃。

栈和队列直接使用切片功能实现即可

//栈
stack:=make([]int,0)//栈初始化

stack=append(stack,E)//入栈

E=stack[len(stack)-1]
stack=stack[:len(stack)-1]//出栈



//队列
queue:=make([]int,0)//队列初始化

queue:=append(stack,E)//入队

E=queue[0]
queue=queue[1:]//出队

go的习惯转变

  1. go没有java这么多的集合类,但是可以用slice和map基本完成leetcode刷题的需求
  2. go语言的平行赋值可以使得变量的交换非常方便:a,b=b,a,不用考虑中间变量。在处理链表的插入更是方便:
//将node插到head后面,同时将node在链表上的位置后移
head.next, node.next, node = node, head.next, node.next
  1. go可以使用多返回值,比如使用go经典的双返回值:(int,ok),ok表示函数是否成功
  2. go的if使用:if d:=dfs(node);d>2可以在判断的同时提取一个局部变量d
  3. go使用标签配合for循环可以一次break跳出多层循环
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值