You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Golang两数之和代码,用更少循环实现线性时间查找?

数组两数之和的优化实现(Go语言)

原实现代码

func FindTwoNumbers(arr []int, target int) {
    for i := 0; i < len(arr); i++ {
        for j := 0; j < len(arr); j++ {
            if arr[i] == arr[j] {
                continue
            }
            if arr[i]+arr[j] == target {
                fmt.Printf("Numbers: %v and %v\n", arr[i], arr[j])
                arr = append(arr[:i], arr[i+1:]...)
                i--
            }

        }

    }
}

func main() {
    FindTwoNumbers([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, 14)
}

原代码运行输出

go run main.go
Numbers: 5 and 9
Numbers: 6 and 8

优化实现方式

原双重循环的时间复杂度为O(n²),可以通过以下两种方式降低时间复杂度,减少循环次数:

方法一:哈希表法(单次循环,时间复杂度O(n))

利用哈希表记录已遍历过的元素,每次遍历当前元素时,计算需要的补数(target - 当前元素),检查补数是否存在于哈希表中。这种方法仅需一次遍历,效率更高,同时通过额外的集合避免重复输出相同数对。

import "fmt"

func FindTwoNumbersWithMap(arr []int, target int) {
    seen := make(map[int]bool)
    outputPairs := make(map[string]bool)

    for _, num := range arr {
        complement := target - num
        if seen[complement] {
            // 统一数对排序格式,避免重复记录(5,9)和(9,5)
            var pairKey string
            if num < complement {
                pairKey = fmt.Sprintf("%d-%d", num, complement)
            } else {
                pairKey = fmt.Sprintf("%d-%d", complement, num)
            }
            if !outputPairs[pairKey] {
                fmt.Printf("Numbers: %v and %v\n", complement, num)
                outputPairs[pairKey] = true
            }
        }
        seen[num] = true
    }
}

func main() {
    FindTwoNumbersWithMap([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, 14)
}

运行输出与原代码一致:

go run main.go
Numbers: 5 and 9
Numbers: 6 and 8

方法二:双指针法(先排序,时间复杂度O(n log n))

先对数组排序,再用左右两个指针从数组两端向中间移动,根据两数之和与目标值的关系调整指针位置:

  • 若和小于目标值,左指针右移
  • 若和大于目标值,右指针左移
  • 若等于目标值,记录结果并同时移动两个指针
import (
    "fmt"
    "sort"
)

func FindTwoNumbersWithTwoPointers(arr []int, target int) {
    // 复制原数组,避免修改原数据
    sortedArr := make([]int, len(arr))
    copy(sortedArr, arr)
    sort.Ints(sortedArr)

    left := 0
    right := len(sortedArr) - 1

    for left < right {
        sum := sortedArr[left] + sortedArr[right]
        if sum == target {
            fmt.Printf("Numbers: %v and %v\n", sortedArr[left], sortedArr[right])
            left++
            right--
        } else if sum < target {
            left++
        } else {
            right--
        }
    }
}

func main() {
    FindTwoNumbersWithTwoPointers([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, 14)
}

运行输出同样一致:

go run main.go
Numbers: 5 and 9
Numbers: 6 and 8

内容的提问来源于stack exchange,提问作者purple hippo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:15:29