3sum(3总和),如果允许重复

时间:2015-04-16 22:21:33

标签: algorithm

与传统的3sum问题相比,如果任何三个元素的总和等于零,则查找所有三元组,我们可以使用任何重复项。 例如,对于输入数组[-2,-1,3,4],( - 2,-2,4)也是一种解决方案。 (-2是重复的,允许)。 我的解决方案是将每个元素分成3个副本,然后将修改后的元素视为传统的3sum问题。但是这种方法在最坏的情况下花费O(2n)空间。是否有可用的恒定空间解决方案?

2 个答案:

答案 0 :(得分:0)

问题有点不清楚,因为您还没有发布您的实际实施。但是,假设standard O(n^2) implementation没有散列:

 sort(S);
 for i=0 to n-3 do
    a = S[i];
    start = i+1;
    end = n-1;
    while (start < end) do
       b = S[start];
       c = S[end];
       if (a+b+c == 0) then
          output a, b, c;
           start = start + 1
           end = end - 1
       else if (a+b+c > 0) then
          end = end - 1;
       else
          start = start + 1;
       end
    end
 end

通过将变量start初始化为i而不是i+1,您可以在解决方案中获得重复项。此外,如果允许最后三元组中的所有元素来自同一个数组元素,则另外将循环条件从while (start < end)更改为while (start <= end)

答案 1 :(得分:0)

我的解决方案:

public static List<List<Integer>> threeSum(int[] nums) {
    Arrays.sort(nums);
    List<List<Integer>> resultList = new ArrayList();
    int start1 = 0;
    while (start1 <= nums.length - 1 - 2) {
        int start2 = start1 + 1;
        int end = nums.length - 1;
        while (true) {
            if (start2 >= end) {
                break;
            }
            int result = nums[start1] + nums[start2] + nums[end];
            if (result == 0) {
                addToResponse(resultList, nums[start1], nums[start2], nums[end]);
                do {
                    start2++;
                } while (start2 < end && nums[start2] == nums[start2 - 1]);
                do {
                    end--;
                } while (end > start2 && nums[end] == nums[end + 1]);
            } else if (result > 0) {
                do {
                    end--;
                } while (end > start2 && nums[end] == nums[end + 1]);
            } else if (result < 0) {
                do {
                    start2++;
                } while (start2 < end && nums[start2] == nums[start2 - 1]);
            }


        }
        do {
            start1++;
        }
        while (nums[start1] == nums[start1 - 1] && start1 < nums.length-1);

    }
    return resultList;
}

private static void addToResponse(List<List<Integer>> result, int a, int b, int c) {
    result.add(Arrays.asList(a, b, c));
}