3Sum and 4Sum Problems

Posted ping1994

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3Sum and 4Sum Problems相关的知识,希望对你有一定的参考价值。

3Sum:

题目: Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

For example, given array S = {-1 2 1 -4}, and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
审题: 输入都是整数,因此与target的最小可能距离为0,当每次获得三个值的和时,首先应该判断一下是否与target相等,也即他们的距离为0,这样可以避免一些多余的计算,减少计算量。

class Solution:
    # @return an integer
    def threeSumClosest(self, num, target):
        num.sort()
        result = num[0] + num[1] + num[2]
        for i in range(len(num) - 2):
            j, k = i+1, len(num) - 1
            while j < k:
                sum = num[i] + num[j] + num[k]
                if sum == target:
                    return sum

                if abs(sum - target) < abs(result - target):
                    result = sum

                if sum < target:
                    j += 1
                elif sum > target:
                    k -= 1

        return result

通过设置左右指针,将一个一般会按照O(N3) 复杂度的问题降低为O(N2)。这里要注意最外面的循环截止N-2,预留两个索引位给两个pointers.

4Sum

题目 Given an array S of n integers, are there elements a, b, c, 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: 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] ]

方案

class Solution:
 def fourSum(self, nums, target):
     def NSum(nums, target, N, result, results):
         if len(nums) < N or N < 2 or target < nums[0]*N or target > nums[-1]*N:
             return
         if N == 2:
             r = len(nums)-1
             l = 0
             while l < r:
                 s = nums[l] + nums[r]
                 if s == target:
                     results.append(result + [nums[l], nums[r]])
                     l += 1
                     while l < r and nums[l] == nums[l-1]:
                         l += 1
                 elif s > target:
                     r -= 1
                 else:
                     l += 1

         else:
             for i in range(len(nums)-N+1):
                 if i == 0 or (i > 0 and nums[i] != nums[i-1]):
                     NSum(nums[i+1:], target-nums[i], N-1, result+[nums[i]], results)

     results = []
     nums.sort()
     NSum(nums, target, 4, [], results)

     return results

解析 (1)这里实现了一个NSum的算法,最底层实现了2Sum问题,然后递归地调用2Sum实现Nsum; (2)在进入代码主体之前,先通过判断排除各种极端和特殊的情形,当然这也算是代码的主体; (3)代码在调用Nsum之前,对相邻两个元素是否相等做了判断,避免相同的数被重复考察;同样地,代码在将左指针向右移动之后,也判断了新的元素是否与刚刚考察过的前一个元素相等,若是相等,则将指针继续右移,减少重复计算;

以上是关于3Sum and 4Sum Problems的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode——18. 4Sum

3Sum & 4Sum

1. Two Sum&&15. 3Sum&&18. 4Sum

4Sum - LeetCode

Leetcode4Sum

LeetCode——4Sum &amp; 总结