【LeetCode with Python】 Two Sum

博客域名: http://www.xnerv.wang
原题页面: https://oj.leetcode.com/problems/two-sum/
题目类型:两点问题
难度评价:★★★
本文地址: http://blog.csdn.net/nerv3x3/article/details/37339471

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2


给定一个数列(注意不一定有序),和一个指定的数值target。从这个数列中找出两个数相加刚好等于target,要求给出这两个数的下标(注意数列下标是从1而不是从0开始)。
首先将数列排序。由于最后要得求的是两个数的原有下标,而不是两个数本身,因此要用一个新的对象Item来封装原有数列元素,并记录该元素的原有下标。排序是针对数列元素本身数值的,分别用一个index1指针和一个index2指针指向排序后的数列的首位,如果指向的两个数相加的和等于target,则搜索结束;如果和小于target,则由于index2此时指向的已经是数组中的最大数了,因此只能令index1向右移动一次;如果和大于target,则由于此时index1已经指向数组中的最小数了,因此只能令index2向左移动一次。用一个循环重复上述过程,直到和等于target宣告搜索成功,或者index1>=index2宣告搜索失败。
空间复杂度O(n),因为构造了一个新的Item序列。时间复杂度方面,如果假设Python的sort算法是用的快速排序的话,那排序的时间复杂度为O(n*logn),搜索过程的时间复杂度为O(n),因此总的时间复杂度为O(n*logn)。
注意给的数列也许长度为0,这样无论target是多少都是搜索失败。而且题目中给的example明显是是在误导人,不仔细看误以为数列原本就有序。此外,数列下标是从1而不是从0开始的。
但是这种算法的前提要先进行一次排序,看起来总是有点不舒服,是不是有更好的算法呢?

class Solution:

    class Item:
        def __init__(self, value, index):
            self.value = value
            self.index = index

    # @return a tuple, (index1, index2)
    def twoSum(self, num, target):
        len_num = len(num)
        if 0 == len_num:
            return (-1, -1)

        items = [Solution.Item(value, 0) for value in num]
        for i in range(0, len_num):
            items[i].index = i + 1
        items.sort(lambda x, y: cmp(x.value, y.value))
        index1 = 0
        index2 = len_num - 1
        is_find = False
        while index1 < index2:
            total = items[index1].value + items[index2].value
            if total < target:
                index1 += 1
            elif total > target:
                index2 -= 1
            else:
                is_find = True
                break
        (index1, index2) = (index1, index2) if items[index1].index <= items[index2].index else (index2, index1)
        return (items[index1].index, items[index2].index) if is_find else (-1, -1)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值