• 18. 4Sum


    Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

    Note:

    • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    • The solution set must not contain duplicate quadruplets.
    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
    
        A solution set is:
        (-1,  0, 0, 1)
        (-2, -1, 1, 2)
        (-2,  0, 0, 2)

    AC代码:

    class Solution(object):
        def fourSum(self, nums, target):
            ret_list = []
            nums.sort()
            for i in xrange(len(nums) - 3):
                if i > 0 and nums[i] == nums[i - 1]: continue
                for j in xrange(i + 1, len(nums) - 2):
                    if j > i + 1 and nums[j] == nums[j - 1]: continue
                    m, n = j + 1, len(nums) - 1
                    while m < n:
                        s = nums[i] + nums[j] + nums[m] + nums[n]
                        if s > target:
                            n -= 1
                        elif s < target:
                            m += 1
                        else:
                            ret_list.append([nums[i], nums[j], nums[m], nums[n]])
                            while m < n and nums[m] == nums[m + 1]:
                                m += 1
                            while m < n and nums[n] == nums[n - 1]:
                                n -= 1
                            m += 1; n -= 1
            return ret_list

    一开始思路是和3Sum一样,所以直接在外面套了一层循环。

    这个代码有两个缺点:

    1.没有跳过一些明显不合法的情况,比如排序后第一个数字乘以4已经比目标数字高了,这种情况下肯定找不到想到的组合,应该直接跳过。

    2.写的不够通用,考虑到以后万一有个5Sum,6Sum……,本代码又要重构。

    所以写了一个支持任意数目组合的通用代码,并且考虑了明显不符合的情况,提高效率。

    class Solution(object):
        def fourSum(self, nums, target):
            def n_sum(nums, target, n, temp_result, ret_list):
                # skip unnecessary calculate
                if len(nums) < n or n < 2 or target < n*nums[0] or target > n*nums[-1]:
                    return
                # almost exactly the same with Two Sum
                if n == 2:
                    i, j = 0, len(nums) - 1
                    while i < j:
                        s = nums[i] + nums[j]
                        if s > target:
                            j -= 1
                        elif s < target:
                            i += 1
                        else:
                            ret_list.append(temp_result + [nums[i], nums[j]])
                            # remove duplicates
                            while i < j and nums[i] == nums[i + 1]:
                                i += 1
                            while i < j and nums[j] == nums[j - 1]:
                                j -= 1
                            i += 1; j -= 1
                else:
                    for i in xrange(len(nums) - n + 1):
                        if i > 0 and nums[i] == nums[i - 1]: continue
                        n_sum(nums[i+1:], target - nums[i], n - 1, temp_result + [nums[i]], ret_list)
    
            ret_list = []
            n_sum(sorted(nums), target, 4, [], ret_list)
            return ret_list

    因为去除掉了一些不必要的计算,本代码在Leetcode中表现要比第一种好很多。

  • 相关阅读:
    clound R
    ubuntu 下安装查看pdf的工具
    统计门户
    neusoft 东软
    一位做数据分析的老师的blog
    ubuntu 下安装查看pdf的工具
    R语言矩阵转置
    取经难,取真经更难。
    R function
    只针对中英文混合分词的中文分词器
  • 原文地址:https://www.cnblogs.com/zhuifengjingling/p/5218816.html
Copyright © 2020-2023  润新知