zoukankan      html  css  js  c++  java
  • [LeetCode#18]4Sum

    Problem:

    Given an array S of n integers, are there elements abc, 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:

    • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    • 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)

    Analysis:

    This problem share the same idea with 2sum, 3sum. (note ask the index, but the combination)
    It involve the test aginst your skills in avoding duplicates. 
    
    Once thing you should keep in mind:
    The duplicate does not mean the same value appear at different index more than one times, but mean the same value appear on the same index more than one time. 
    ---------------------------------------------------------------------------
    Case: 
    case a: 1 1 2 2 ... 
    This would not cause duplicate.
    case b: 1(1) ....
    This would cause duplicate.
    The case b is the situation we should exclude, but we should incldue case a. 
    ---------------------------------------------------------------------------
    Arrays.sort(nums);
    The classic way to exlude duplicates on the same index is to take advantage of sorted array. 
    Arrays.sort(nums);
    1. avoid duplicates at first element (item[0]).
    if (i == 0 || nums[i] != nums[i-1])
    Note: nums[i] != nums[i-1] is a very classic method.
    
    2. avoid duplicates at second element (item[1]).
    if (j == i+1 || nums[j] != nums[j-1])
    Note: why we can start from i+1, cause case a!!!
    
    3. avoid the duplicate at third element (item[2])
    front++;
    while (front < nums.length && nums[front] == nums[front-1]) {
        front++;
    }
    Note: the above is a very great skill in two sum, when using front and pointer. 
    
    4. avoid the duplicate at fourth element (item[3])
    You can see there is obvious code for avoding the last index's duplicate at 2sum, 3sum, and 4sum. The reason is, once we find out the answer, we immediately move front to the next element with different value. 
    since nums[front] + nums[end] = target.
    nums[new_front] + nums[end] must not equal to target. This guarantee there is no duplicates for the last index!!!
    
    if (nums[front] + nums[end] == target) {
        ...
        front++;
        while (front < nums.length && nums[front] == nums[front-1]) {
            front++;
        }
    }

    Solution:

    public class Solution {
        public List<List<Integer>> fourSum(int[] nums, int target) {
            if (nums == null)
                throw new IllegalArgumentException("nums reference is null");
            List<List<Integer>> ret = new ArrayList<List<Integer>> ();
            if (nums.length <= 3)
                return ret;
            Arrays.sort(nums);
            for (int i = 0; i <= nums.length - 4; i++) {
                for (int j = i+1; j <= nums.length - 3; j++) {
                    if (i == 0 || nums[i] != nums[i-1]) {
                        if (j == i+1 || nums[j] != nums[j-1]) {
                            twoSum(nums, nums[i], nums[j], j+1, target-nums[i]-nums[j], ret);
                        }
                    }
                }
            }
            return ret;
        }
        
        
        private void twoSum(int[] nums, int num1, int num2, int front, int target, List<List<Integer>> ret) {
            int end = nums.length - 1;
            while (front < end) {
                if (nums[front] + nums[end] == target) {
                    ArrayList<Integer> item = new ArrayList<Integer> ();
                    item.add(num1);
                    item.add(num2);
                    item.add(nums[front]);
                    item.add(nums[end]);
                    ret.add(item);
                    front++;
                    while (front < nums.length && nums[front] == nums[front-1]) {
                        front++;
                    }
                } else if (nums[front] + nums[end] < target) {
                    front++;
                } else {
                    end--;
                }
            }
        }
    }
  • 相关阅读:
    Ceph14.2.5 RBD块存储的实战配置和详细介绍,不看后悔! -- <3>
    常见SQL命令总结学习 -- <1>
    全网最详细的新手入门Mysql命令和基础,小白必看!
    全网最详细的Linux命令系列-nl命令
    全网最详细的Linux命令系列-cat命令
    全网最详细的Linux命令系列-touch命令
    全网最详细的Ceph14.2.5集群部署及配置文件详解,快来看看吧! -- <2>
    什么是Ceph存储?什么是分布式存储?简单明了带你学Ceph -- <1>
    一款专注于阅读的博客园主题-(cnblogs-theme-silence)
    Prometheus 配置文件中 metric_relabel_configs 配置--转载
  • 原文地址:https://www.cnblogs.com/airwindow/p/4784353.html
Copyright © 2011-2022 走看看