• 3Sum


    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

    Note:

    • Elements in a triplet (a,b,c) must be in non-descending order. (ie, abc)
    • The solution set must not contain duplicate triplets.
        For example, given array S = {-1 0 1 2 -1 -4},
    
        A solution set is:
        (-1, 0, 1)
        (-1, -1, 2)
    
     

    分析:

    这个问题是要从数列里面找到所有和是0的3个数。

    对程序输出有两个限制,一是输出的三元组要按升序排列,二是输出的数列要去重,这在编码中会无法避免的导致检查和去重的代码实现。

    用map来实现过滤的话,会很容易导致超时,但是在实际应用中,还是觉得用map自动处理比较好理解,而且代码稳定易读。

    我写了一个函数,用来清楚表明3 Sum与2 Sum的区别。在这个twoSum里面实现了另外一种Two Sum的解法,略有差别是因为本题不需要返回索引,只要得到正确的数就可以了,所以省略了记录索引的步骤。

    class Solution:
    
        # @return a list of lists of length 3, [[val1,val2,val3]]
        def threeSum(self, num):
            values = []
    
            num.sort()
            for i, c in enumerate(num[:-2]):
                if c > 0:
                    break
                if i == 0 or num[i] > num[i - 1]:
                    values.extend(self.twoSum(num, c, i + 1))
            return values
    
        def twoSum(self, num, c, start):
            '''Another way for two sum problem'''
            c = -c
            values = []
            end = len(num) - 1
            while start < end:
                if num[start] + num[end] == c:
                    values.append([-c, num[start], num[end]])
                    start += 1
                    end -= 1
    
                    while start < end and num[start] == num[start - 1]:
                        start += 1
                    while start < end and num[end] == num[end + 1]:
                        end -= 1
                elif num[start] + num[end] < c:
                    start += 1
                else:
                    end -= 1
            return values
    
    if __name__ == '__main__':
        s = Solution()
        assert s.threeSum([-1, 0, 1, 2, -1, -4]) == [[-1, -1, 2], [-1, 0, 1]]
        assert s.threeSum([0, 0, 0]) == [[0, 0, 0]]
        assert s.threeSum([-2, 0, 1, 1, 2]) == [[-2, 0, 2], [-2, 1, 1]]
        assert s.threeSum([1, -1, -1, 0]) == [[-1, 0, 1]]
        print 'PASS'

    小结:

    这个问题与TwoSum结合起来思考的话并不难,但是如果考虑4个数值的衍生情况,是否是O(n^3)的复杂度?

    我附带贴上一个更为简洁的代码,但是无法过LeetCode的Online Judge,原因是为了代码的易读可靠超时了。LeetCode不支持set这个数据结构,否则

    values = set()

    更为简洁,避免了要给dict的value赋上一个值。

    def threeSum2(self, num):
            '''This solution much clear but time out'''
            values = {}
            table = dict(zip(num, range(len(num))))
            for i, c in enumerate(num[:-2]):
                for j, b in enumerate(num[i + 1:], i + 1):
                    a = -c - b
                    if a in table and table[a] not in (i, j):
                        values[tuple(sorted((a, b, c)))] = 1
    
            return map(list, values.keys())
  • 相关阅读:
    Python pyspider 安装与开发
    Shell curl 和 wget 使用代理IP
    米扑代理示例(mimvp-proxy-demo)
    图片加载失败如何替换成默认图片
    Node-mongodb链接数据库函数的封装
    移动端拼图效果实现
    JS调用百度地图API获取地理位置
    The Begin
    Matlab(Client)和Python(Server)进行TCP通信
    ubuntu如何有效扩容根目录的记录(实践有效ubuntu20.0版本)
  • 原文地址:https://www.cnblogs.com/openqt/p/4038762.html
Copyright © 2020-2023  润新知