[leetcode]4Sum

这道4Sum,如果用3Sum类似的方法,是O(n^3)的复杂度。现在使用O(n^2)的空间呢,能达到O(n^2)的时间复杂度。但实现起来坑还是不少,一是要去重,用了string来表示集合的key;二是不能同一个索引位置的数(num[i])出现两次,所以要做下标的检查;三是当左右相加等于target的时候,现在不能直接跳过大小一样的,因为同样大小的可能是a+b也可能是c+d,就要l++和r--递归来做。但用递归有可能爆栈(Runtime Error),就用了Stack来模拟递归。最终Java 1472ms过。

后来参考方勤的版本,如果用map来存sum=>pair,在只求解(而非全部解)的情况下,可以O(n^2)写得更简洁。

import java.util.*;

public class Solution {

    private ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();

    private HashSet<String> ansSet = new HashSet<String>();

    private HashSet<String> posSet = new HashSet<String>();

    public ArrayList<ArrayList<Integer>> fourSum(int[] num, int target) {

        ans.clear();

        ansSet.clear();

        posSet.clear();

        Arrays.sort(num);

        int len = num.length;

        ArrayList<Pair> pairs = new ArrayList<Pair>();

        for (int i = 0; i < len; i++)

        {

            for (int j = i+1; j < len; j++)

            {

                pairs.add(new Pair(num[i], num[j], i, j));

            }

        }

        Collections.sort(pairs);

        Stack<Integer> stack = new Stack<Integer>();

        stack.push(0); stack.push(pairs.size()-1);

        while (!stack.empty())

        {

            int r = stack.pop();

            int l = stack.pop();

            if (l >= r) continue;

            String posKey = "" + l + "_" + r;

            if (posSet.contains(posKey)) continue;

            else posSet.add(posKey);

            int sum = pairs.get(l).sum + pairs.get(r).sum;

            if (sum < target)

            {

                stack.push(l+1);

                stack.push(r);

            }

            else if (sum > target)

            {

                stack.push(l);

                stack.push(r-1);

            }

            else // ==

            {

                if (pairs.get(l).aIdx != pairs.get(r).aIdx &&

                    pairs.get(l).aIdx != pairs.get(r).bIdx &&

                    pairs.get(l).bIdx != pairs.get(r).aIdx &&

                    pairs.get(l).bIdx != pairs.get(r).bIdx)

                {

                    // add to result;

                    ArrayList<Integer> arr = new ArrayList<Integer>();

                    arr.add(pairs.get(l).a);

                    arr.add(pairs.get(l).b);

                    arr.add(pairs.get(r).a);

                    arr.add(pairs.get(r).b);

                    Collections.sort(arr);

                    String key = "";

                    for (int k = 0; k < 4; k++)

                    {

                        key = key + arr.get(k) + "_";

                    }

                    if (!ansSet.contains(key))

                    {

                        ansSet.add(key);

                        ans.add(arr);

                    }

                }     

                stack.push(l);

                stack.push(r-1);

                stack.push(l+1);

                stack.push(r);

            }

        }

        return ans;

    }

}



class Pair implements Comparable<Pair>

{

    int a;

    int b;

    int sum;

    int aIdx;

    int bIdx;

    

    public Pair (int a, int b, int aIdx, int bIdx)

    {

        this.a = a;

        this.b = b;

        this.sum = a + b;

        this.aIdx = aIdx;

        this.bIdx = bIdx;

    }

    

    public int compareTo(Pair that)

    {

        return this.sum - that.sum;

    }

}

  

 

你可能感兴趣的:(LeetCode)