继续做脑力运动刷LeetCode,今天继续使用go来做开发,随机刷了一道编号718的题:Add Two Numbers,中文名叫最长重复子数组,难度:中等。
题目要求如下:
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
示例 1:
输入:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
输出: 3
解释:
长度最长的公共子数组是 [3, 2, 1]。
说明:
1 <= len(A), len(B) <= 1000
0 <= A[i], B[i] < 100
题目偏简单了,就当熟悉go语言规范了,循环结构和条件语句不熟悉。
官方一共54个test case,放一个最终结果吧
执行用时 : 236 ms, 在所有 Go 提交中击败了 6.60% 的用户 内存消耗 : 3.4 MB, 在所有 Go 提交中击败了 100.00% 的用户
详细信息参考这里 最长重复子数组 - 提交记录 - 力扣 (LeetCode) ,执行时间有点出乎意料。
再去英文版检查一下
Runtime: 184 ms, faster than 5.88% of Go online submissions for Maximum Length of Repeated Subarray. Memory Usage: 3.4 MB, less than 100.00% of Go online submissions for Maximum Length of Repeated Subarray.
详细信息参考这里 Maximum Length of Repeated Subarray - Submission Detail - LeetCode ,一样的效果,执行时间有点太长。
先解释一下思路:
- 以其中一个数组的遍历作为主循环
- 开始逐段比较,如果相同就继续
- 如果失败,重置内循环的计数器j到lastIndexJ
- 如果内循环的计数器j到头了,那么就记录结果,重置主循环的计数器i到lastIndexI
- 优化思路时,当发现已有当长度少于之前的结果,就停止或开始下一段的比较
package main
func findLength(A []int, B []int) int {
var result, lastResult, lastIndexI, lastIndexJ = 0, 0, 0, 0
for i, j := 0, 0; i < len(A); {
if A[i] == B[j] {
result++
i++
j++
if lastResult < result {
lastResult = result
}
} else {
i = lastIndexI
lastIndexJ++
j = lastIndexJ
result = 0
}
if j >= len(B) || len(B)-lastIndexJ <= lastResult {
lastIndexI++
i = lastIndexI
if len(A)-i <= lastResult {
break
}
j, lastIndexJ = 0, 0
result = 0
}
}
return lastResult
}
还有测试用例,大部分取自官方测试用例集合,包含大多数典型情况。
package main
import "testing"
func Test_findLength(t *testing.T) {
type args struct {
A []int
B []int
}
tests := []struct {
name string
args args
want int
}{
{"第一个测试", args{[]int{1, 2, 3, 2, 1}, []int{3, 2, 1, 4, 7}}, 3},
{"第二个测试", args{[]int{}, []int{}}, 0},
{"第三个测试", args{[]int{1}, []int{1}}, 1},
{"第四个测试", args{[]int{1}, []int{2}}, 0},
{"第五个测试", args{[]int{0, 0, 0, 0, 1}, []int{1, 0, 0, 0, 0}}, 4},
{"第六个测试", args{[]int{0, 0, 0, 0, 0}, []int{0, 0, 0, 0, 0}}, 5},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := findLength(tt.args.A, tt.args.B); got != tt.want {
t.Errorf("findLength() = %v, want %v", got, tt.want)
}
})
}
}
收获
这次这个有点花时间和思路,主要是优化计算时间上面,虽然结果对了,貌似计算时长比平均值差不少,今天有空再看看标准解法,看看有没有啥收获。