1. 程式人生 > >3Sum and 4Sum Problems

3Sum and 4Sum Problems

遞歸 pos 繼續 可能 problem which return append assume

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