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

 

posted @ 2021-02-05 16:34  qilibin  阅读(61)  评论(0编辑  收藏  举报