Leetcode 15 3Sum

HowieLee59發表於2018-10-11

Given an array nums of n integers, are there elements abc in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

這個題想要求的是在一串陣列中的三個數,使之相加等於0,使用的類似於二分的思想,在剛開始敲完之後一直是超時的超空間的,在調整三個數相加等於0的情況後解決掉了。

1)

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        ArrayList<List<Integer>> list = new ArrayList<List<Integer>>();
        for(int i = 0 ; i < nums.length - 2;i++){
            if(i != 0 && nums[i] == nums[i - 1]){
                continue;
            }
            int left = i + 1;
            int right = nums.length - 1;
            while(left < right){
                int n = nums[left] + nums[right];
                if(nums[i] + n == 0){
                    ArrayList<Integer> li = new ArrayList<>();
                    li.add(nums[i]);
                    li.add(nums[left]);
                    li.add(nums[right]);
                    list.add(li);
                    left++;
                    right--;
                    while(left < right && nums[left] == nums[left - 1]){
                        left++;
                    }
                    while(left < right && nums[right] == nums[right + 1]){
                        right--;
                    }
                }else if(nums[i] + n < 0){
                    left++;
                }else{
                    right--;
                }
            }
        }
        return list;
    }
}

2)

/* Leetcode中時間複雜度最低的--為自動機考慮的多了,時間就降下來了 */
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
      if (nums.length < 3)
        return Collections.emptyList();
      List<List<Integer>> res = new ArrayList<>();
      int minValue = Integer.MAX_VALUE;
      int maxValue = Integer.MIN_VALUE;
      int negSize = 0;
      int posSize = 0;
      int zeroSize = 0;
      for (int v : nums) {
        if (v < minValue)
          minValue = v;
        if (v > maxValue)
          maxValue = v;
        if (v > 0)
          posSize++;
        else if (v < 0)
          negSize++;
        else
          zeroSize++;
      }
      if (zeroSize >= 3)
        res.add(Arrays.asList(0, 0, 0));
      if (negSize == 0 || posSize == 0)
        return res;
      if (minValue * 2 + maxValue > 0)
        maxValue = -minValue * 2;
      else if (maxValue * 2 + minValue < 0)
        minValue = -maxValue * 2;

      int[] map = new int[maxValue - minValue + 1];
      int[] negs = new int[negSize];
      int[] poses = new int[posSize];
      negSize = 0;
      posSize = 0;
      for (int v : nums) {
        if (v >= minValue && v <= maxValue) {
          if (map[v - minValue]++ == 0) {
            if (v > 0)
              poses[posSize++] = v;
            else if (v < 0)
              negs[negSize++] = v;
          }
        }
      }
      Arrays.sort(poses, 0, posSize);
      Arrays.sort(negs, 0, negSize);
      int basej = 0;
      for (int i = negSize - 1; i >= 0; i--) {
        int nv = negs[i];
        int minp = (-nv) >>> 1;
        while (basej < posSize && poses[basej] < minp)
          basej++;
        for (int j = basej; j < posSize; j++) {
          int pv = poses[j];
          int cv = 0 - nv - pv;
          if (cv >= nv && cv <= pv) {
            if (cv == nv) {
              if (map[nv - minValue] > 1)
                res.add(Arrays.asList(nv, nv, pv));
            } else if (cv == pv) {
              if (map[pv - minValue] > 1)
                res.add(Arrays.asList(nv, pv, pv));
            } else {
              if (map[cv - minValue] > 0)
                res.add(Arrays.asList(nv, cv, pv));
            }
          } else if (cv < nv)
            break;
        }
      }
      return res;
    }
}