# 两数之和 (题167) --- :::success ```go= 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 说明: 返回的下标值(index1 和 index2)不是从零开始的。 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 示例: 输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 ``` ::: - **1. 暴力解法** :::success ```go= // 时间复杂度 n*n func twoSum(nums []int, target int) []int { length := len(nums) result := make([]int, 0) if length < 2 { return result } for i := 0; i < length; i++ { for j := i + 1; j < length; j++ { if nums[i] + nums[j] == target { result = append(result, i, j) return result } } } return result } ``` ::: - **2. 两次遍历哈希表** :::success ```go= // 时间复杂 O(n) func twoSum(nums []int, target int) []int { maps := make(map[int]int, 0) // 记得使用之前要先初始化,不然会抛异常 result := make([]int, 0) length := len(nums) if length < 2 { return result } for key, value := range nums { maps[value] = key } //然后在map中寻找符合target的要求的值 for i, v := range nums { // 同样的元素不能被重复利用,记得注意不能是自己本身 if _, ok := maps[target - v]; ok && maps[target - v] != i { result = append(result, i, maps[target - v]) break } } return result } ``` ::: - **3. 1次遍历哈希表** :::success ```go= // 时间复杂度O(n) func twoSum(nums []int, target int) []int { maps := make(map[int]int, 0) result := make([]int, 0) length := len(nums) if length < 2 { return result } for key, value := range nums { if i, ok := maps[target - value]; ok { //如果找到,直接return下标 result = append(result, i, key) break } //没有找到储存到map maps[value] = key } return result } ``` ::: - **4. 双指针** :::success ```go= // 时间复杂度O(n) func twoSum(nums []int, target int) []int { length := len(nums) result := make([]int, 0) if length < 2 { return result } left, right := 0, length - 1 for left < right { if nums[left] + nums[right] > target { right-- } else if nums[left] + nums[right] < target { left++ } else { result = append(result, left + 1, right + 1) break } } return result } ``` ::: - **4. 双指针+二分法** :::success ```go= // 时间复杂度O(logn~n) func binarySearch(arr []int, left, right, target int) int { // 二分查找 for left < right { mid := (left + right) / 2 if arr[mid] < target { left = mid + 1 } else { right = mid } } return left } func twoSum(numbers []int, target int) []int { length := len(numbers) - 1 result := make([]int, 0) if length < 1 { return result } j := length for i := 0; i < j; i++ { j = binarySearch(numbers, i + 1, j, target - numbers[i]) // 这里是先做了减法 if numbers[i] + numbers[j] == target { result = append(result, i + 1, j + 1) break // 如果想要找到所有的数组对,可以这样修改,替换上面的两句代码 // result = append(result, numbers[i], numbers[j]) } } return result } ``` ::: ###### tags: `LeeCode`