微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用HashSetHashTable解决方案的2Sum,3Sum,4Sum ........ kSum

如何解决使用HashSetHashTable解决方案的2Sum,3Sum,4Sum ........ kSum

我正在解决问题。问题在下面给出-

给定一个由n个整数组成的数组和一个整数目标,是否存在以a为单位的元素a,b,c和d,使得a + b + c + d = target?在数组中找到给出目标总和的所有唯一四元组

注意:

解决方案集不得包含重复的四元组

给出数组nums = [-1,1,2,-1,-4]target = -1

解决方案集是:

[[-4,2],[-1,1]]

下面给出了该问题的代码-

class Solution {

List<List<Integer>> output=new ArrayList();
    

public List<List<Integer>> fourSum(int[] nums,int target) {

    Arrays.sort(nums);
    
    for(int i=0;i<nums.length;i++){
        if(i==0 || nums[i-1]!=nums[i]){
            for(int j=i+1;j<nums.length;j++){                
                if(j==1 || nums[j-1]!=nums[j]){
                    calculate(nums,i,j,target);
                }
            }
        }
    }
    return output;
        
}

public void calculate(int[] nums,int i,int j,int target){
    
    Set<Integer> hashSet=new HashSet();
    for(int k=j+1; k<nums.length;k++){
        int vector=target-nums[i]-nums[j]-nums[k];
        if(hashSet.contains(vector)){
            output.add(Arrays.asList(nums[i],nums[j],nums[k],vector));
            while(k+1<nums.length && nums[k]==nums[k+1]){
                k++;                                        
            }
                
        }            
        hashSet.add(nums[k]);
    }
    
}

}

我的输出是:[[-4,1]]

但预期输出为:[[-4,1]]

请帮助!

要按照我执行的步骤解决此问题。

 A) For the main function:

     1. Sort the input array nums.
     2. Iterate through the array for 2 times (i,j):
         If the current value is greater than zero,break from the 
         loop. Remaining values cannot sum to zero.
         If the current value is the same as the one before,skip it.
         Otherwise,call twoSum for the current position i.

  B) For calculate function:

      1. For each index k > j in A:
      2. Compute complement vector = target -nums[i] - nums[j].
      3. If complement exists in hashset seen:
      4. We found a triplet - add it to the result res.
      5. Increment k while the next value is the same as before to 
         avoid duplicates in the result.

   C) Add nums[k] to hashset seen
   D) Return the result output.

解决方法

问题在(j==1 || nums[j-1]!=nums[j])(i==0 || nums[i-1]!=nums[i])

static List<List<Integer>> output;
public static void main (String[] args) throws Exception{
    output = new ArrayList<>();
    fourSum(new int[]{0,0},0);
    System.out.println(output);
}

public static void fourSum(int[] nums,int target) {
    Arrays.sort(nums);
    for(int i=0;i<nums.length;i++){
        for(int j=i+1;j<nums.length;j++){
            calculate(nums,i,j,target);
        }
    }
}

public static void calculate(int[] nums,int i,int j,int target){
    Set<Integer> hashSet=new HashSet();
    for(int k=j+1; k<nums.length;k++){
        int vector=target-nums[i]-nums[j]-nums[k];
        if(hashSet.contains(vector)){
            output.add(Arrays.asList(nums[i],nums[j],nums[k],vector));
            while(k+1<nums.length && nums[k]==nums[k+1]){
                k++;                                        
            }
        }            
        hashSet.add(nums[k]);
    }
}

输入:{0,0},目标:0:输出:[[0,0]]

输入:{-1,1,2,-1,-4},目标:-1,输出:[[-4,2,1],[-1,-1,0]]

,

此问题是3Sum的跟进。 4Sum和3Sum非常相似;区别在于我们正在寻找独特的四联体而不是三联体。

按照类似的逻辑,我们可以通过将4Sum包装在另一个循环中来实现5Sum。但是6Sum,7Sum等等呢?最好我们选择kSum解决方案。以下代码将适用于2Sum,3Sum,4Sum等。

class Solution {

 public List<List<Integer>> fourSum(int[] nums,int target) {
    Arrays.sort(nums);
    int start=0;
    int k=4;
    return this.kSum(nums,target,start,k);            
 }

 public List<List<Integer>> kSum(int[] nums,int target,int start,int k){
    
    List<List<Integer>> output= new ArrayList<>();
    
    if(start==nums.length || nums[start] * k>target || nums[nums.length-1]*k<target)
        return output;
    
    if(k==2)
       return this.twoSum(nums,start);
    for(int i=start;i<nums.length;i++){
        if(i==start || nums[i-1]!=nums[i])
            for(var set: kSum(nums,target-nums[i],i+1,k-1)){
                output.add(new ArrayList<>(Arrays.asList(nums[i])));
                output.get(output.size()-1).addAll(set);
            }
        
    }
    return output;
    
    
 }

 public List<List<Integer>> twoSum(int[] nums,int Target,int start){
    
    
    List<List<Integer>> output=new ArrayList<>();
    Set<Integer> set=new HashSet<>();
    
    for(int i=start;i<nums.length;i++){
        if(output.isEmpty() || output.get(output.size()-1).get(1) !=nums[i]){
            int vector=Target-nums[i];
            if(set.contains(vector)){
                output.add(Arrays.asList(vector,nums[i]));
            }
        }
        set.add(nums[i]);
    }
    
    return output;
 }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。