LeetCode1两数之和
# coding:utf-8 """ Name : LeetCode1.py Author : qlb Contect : 17801044486@163.com Time : 2021/2/5 15:26 Desc: 两数之和 """ from typing import List #解题思路1 暴力解法 双层循环 class Solution1: def twoSum(self, nums: List[int], target: int) -> List[int]: for i in range(len(nums)): for j in range(i+1,len(nums)): if nums[i] + nums[j] == target: return [i,j] #解题思路2 空间换时间 提前将数组存在一个字典中 字典的键为元素的值 字典的值为元素的索引值 # 这样在遍历的时候 时间复杂度为O(n) class Solution2: def twoSum(self, nums: List[int], target: int) -> List[int]: sumDict = {} for i in range(len(nums)): sumDict[str(nums[i])] = i for i in range(len(nums)): if str(target - nums[i]) in sumDict and sumDict[str(target - nums[i])] != i: return [sumDict[str(target - nums[i])],i] # 一边遍历数组一边构建字典 字典初始是空的 [sumDict[target - nums[i]]取到的索引值总是在 当前索引值i之前的 # 最后的两个索引值永远不可能相同 i每增加一次 就和 保存在字典中的 索引为 0 到 i-1 的元素的值比较一轮 class Solution3: def twoSum(self, nums: List[int], target: int) -> List[int]: sumDict = {} for i in range(len(nums)): if target - nums[i] in sumDict: return [sumDict[target - nums[i]],i] sumDict[nums[i]] = i
#双指针解法 # 排序之前一定复制一个数组 因为要拿到在原始数组中的索引 后面排序会破坏原始数组 # 首先将数组排序,这是关键。拍过序的数组前面小 后面大 # 两个指针 前面的小指针i从0开始 后面的大指针j从数组最后一位开始 # 如果nums[i] + nums[j] > target 则nums[j]太大 将j向左移动 # 如果nums[i] + nums[j] < target 则nums[i]太小 将i向右移动 # 如果nums[i] + nums[j] = target 返回 i j索引 class Solution4: def twoSum(self, nums: List[int], target: int) -> List[int]: copy_of_nums = list(nums) i = 0 j = len(nums)-1 nums.sort() while i < j: if nums[i] + nums[j] == target: #如果nums[i] = nums[j] 直接在原始数组里面取索引就会出问题 #如果是直接返回元素值就很简单 题目要求返回索引值 所以取了i1 之后 要把i1 在原始数组中对应的元素剔除 # 避免 nums[i] = nums[j] 的时候 j1 取的值和 i1相同 i1 = copy_of_nums.index(nums[i]) copy_of_nums.pop(i1) j1 = copy_of_nums.index(nums[j]) # 如果j1取得的值比i1小 则不影响j1的实际索引 如果j1取得的值大于等于i1 则j1实际的值应该是j1 + 1 if j1 >= i1: j1 = j1 + 1 return [i1,j1] elif nums[i] + nums[j] > target: j -= 1 else: i += 1