题目:两数之和

描述:给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。

数据范围:2≤len(numbers)≤1500,−10≤numbers≤10^9,0≤target≤10^9

要求:空间复杂度 O(n),时间复杂度 O(nlogn)

例如: 给出的数组为 [20, 70, 110, 150] , 目标值为90

返回一个数组 [1,2] ,因为 numbers_1+numbers_2=20+70=90

思路:这个题目比较麻烦的是时间复杂度要O(nlogn),简单的代码直接用for循环套for循环,挨个遍历,最后时间复杂度为n(n-1),空间复杂度为1,一开始每思路,但是既然是数组,又有logn,第一个想到的就是二分,而二分是得数组有序,所以我就先排序,然后再二分。排序用另一个数组存,排序的过程是取出一个数,然后用二分和存入的数组比较,确定插入位置,存入数组的为数组下标。分了2-3个数组,一个存大于sum/2,另一个存小于sum/2,还有一个存等于sum/2的,之后计算和,用小于sum/2的数组中的数和大于sum/2的数组中的数求和,用二分的方式去遍历。可以稍微优化一下,用两个数组中长度较短的去二分查找另一个长度较长的数组。

我一开始还想在插入数据的时候顺便去遍历,好像也可以,比较后,如果大于sum/2,就去遍历小于sum/2的数组,不用担心有遗漏,因为如果结果为[A,B],而A先进入数组,去遍历的时候没有找到B,但是后来B进数组的时候,一定可以找到A。我去写代码,一会再来更新。

已添加了解法二

```#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param numbers int整型一维数组 
# @param target int整型 
# @return int整型一维数组
#
class Solution:
    @staticmethod
    def saveIn(i,numbers,r):
        mi = 0
        ma = len(r)
        middle = int((ma+mi)/2)
        while(ma > mi):
            middle = int((ma+mi)/2)
            if numbers[i] > numbers[r[middle]]:
                mi = middle+1
            elif numbers[i] < numbers[r[middle]]:
                ma = middle-1
            else:
                mi = middle
                break
        if mi == len(r):
            r.append(i)
        elif numbers[i] < numbers[r[mi]]:
            r.insert(mi,i)
        elif (mi+1)==len(r):
            r.append(i)
        else:
            r.insert(mi+1,i)
            
    def twoSum(self , numbers: List[int], target: int) -> List[int]:
        # write code here
        smaller = []
        bigger = []
        middle = int(target/2)
        r = []
        ri = -1
        for i in range(len(numbers)):
            if numbers[i] < middle:
                self.saveIn(i,numbers,smaller)
            elif numbers[i] > middle:
                self.saveIn(i,numbers,bigger)
            else:
                r.append(i+1)
        if len(r) == 2:
            return r
        for j in smaller:
            ma = len(bigger)-1
            mi = 0
            middle = int((ma+mi)/2)
            while ma > mi:
                middle = int((ma+mi)/2)
                if numbers[j] + numbers[bigger[middle]] == target:
                    ri = middle
                    break
                elif numbers[j] + numbers[bigger[middle]] < target:
                    mi = middle + 1
                else:
                    ma = middle -1
            if (numbers[j] + numbers[bigger[mi]]) == target:
                ri = mi
            elif (numbers[j] + numbers[bigger[ma]]) == target:
                ri = ma
            elif numbers[j] + numbers[bigger[middle]] == target:
                ri = middle
            if ri > -1:
                if bigger[ri] > j:
                    r = [j+1,bigger[ri]+1]
                else:
                    r = [bigger[ri]+1,j+1]
                return r



# 解法二
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param numbers int整型一维数组 
# @param target int整型 
# @return int整型一维数组
#
class Solution:
    @staticmethod
    def saveIn(i,numbers,r):
        mi = 0
        ma = len(r)
        middle = int((ma+mi)/2)
        while(ma > mi):
            middle = int((ma+mi)/2)
            if numbers[i] > numbers[r[middle]]:
                mi = middle+1
            elif numbers[i] < numbers[r[middle]]:
                ma = middle-1
            else:
                mi = middle
                break
        if mi == len(r):
            r.append(i)
        elif numbers[i] < numbers[r[mi]]:
            r.insert(mi,i)
        elif (mi+1)==len(r):
            r.append(i)
        else:
            r.insert(mi+1,i)
    @staticmethod
    def compa(numbers,target,j,arr):
        if len(arr) == 0:
            return []
        ma = len(arr)-1
        mi = 0
        middle = int((ma+mi)/2)
        ri = -1
        while ma > mi:
            if numbers[j] + numbers[arr[middle]] == target:
                ri = middle
                break
            elif numbers[j] + numbers[arr[middle]] < target:
                mi = middle + 1
            else:
                ma = middle -1
            middle = int((ma+mi)/2)
        if (numbers[j] + numbers[arr[mi]]) == target:
            ri = mi
        elif (numbers[j] + numbers[arr[ma]]) == target:
            ri = ma
        elif numbers[j] + numbers[arr[middle]] == target:
            ri = middle
        if ri > -1:
            if ri < j:
                return [arr[ri]+1,j+1]
            else:
                return [j+1,arr[ri]+1]
        return []
    def twoSum(self , numbers: List[int], target: int) -> List[int]:
        # write code here
        smaller = []
        bigger = []
        middle = int(target/2)
        r = []
        r_mid = []
        ri = -1
        for i in range(len(numbers)):
            if numbers[i] < middle:
                r = self.compa(numbers,target,i,bigger)
                if len(r) == 2:
                    return r
                self.saveIn(i,numbers,smaller)
            elif numbers[i] > middle:
                r = self.compa(numbers,target,i,smaller)
                if len(r) == 2:
                    return r
                self.saveIn(i,numbers,bigger)
            else:
                r_mid.append(i+1)
        if len(r_mid) == 2:
            return r_mid