4Sum

225 篇文章 0 订阅
50 篇文章 0 订阅

实现的时候参考了http://blog.sina.com.cn/s/blog_71d59f9a01018dh3.html 的思路。

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)

这道题如果暴力破解的话可以想到复杂度比较高。当时在考虑是否能够拿递归来做,但是想了很久也不知道该怎么做。之前做过一道最大盛水容积的题,思路是宽由大变小的搜索最大容积,我觉得思路可以拿过来思考这道题。那么这样来看,四个参数有两个已经定上了,还需要考虑另外两个变量。由于不能够保存重复的结果,所以最好还是先排序下。(一开始是这么想的,无论后面干什么先排下序。后来发现排序是有好处的)既然已经排好序了,那么可以从收尾的中间开始寻找是否有满足条件的结果。扫的方式是由左边界的右侧一位开始,右边界的左侧一位开始。如果结果计算小于target值,那么说明小的那部分要变大一些,因此p1++;同理,如果大于target值,说明右侧的值需要变小,p2--。至此发现排序是有好处的。 再就是注意去重就好了,用arraylist自带的方法就可以了。

代码:

package leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.text.html.HTMLDocument.Iterator;

public class FourSum {

	public static void main(String[] args) {
		FourSum four = new FourSum();
		int[] nums={1,3,5,7,4,8,8,10};
		int [] nums2={1, 0, -1, 0, -2, 2,0,-2};
		List<List<Integer>> res = four.fourSum(nums2, 0);
	
       System.out.println("result:");
		for (List<Integer> list : res) {
			for (Integer integer : list) {
				System.out.print(integer+" ");
			}
			System.out.println();
		}
	}

     public List<List<Integer>> fourSum(int[] nums, int target) {
        //固定两头 里面两个指针往中间扫,如何想办法去重
    	 
    	 List<List<Integer>> res =new ArrayList<List<Integer>>();
    	 int len = nums.length;
    	 //先排序
    	 Arrays.sort(nums);
    	/* for(int i=0;i<len;i++){
    		 System.out.println(nums[i]);
    	 }*/
    	 //注意范围
    	 for(int i=0;i<len-3;i++){
    		 for(int j = len-1; j > i+2; j--) {
    			//两边的暂时固定,里边选中间的两位
    			 int p1  = i+1;
    			 int p2  = j-1;
    			 int fandl = nums[i]+nums[j];
    			 int tar2 = target - fandl;
    			 while(p1<p2){
    				 //如果有满足条件的加入到res中,还要判断去重
    				 int sandt = nums[p1]+nums[p2];
    				 if(sandt == tar2){
    					 ArrayList temp =new ArrayList<Integer>();
    					 temp.add(nums[i]);
    					 temp.add(nums[p1]);
    					 temp.add(nums[p2]);
    					 temp.add(nums[j]);
    					 if(! res.contains(temp)){
    						 res.add(temp);
    					 }
    					
    					 p1++;
    					 p2--;
    					 
    				 }
    				 else if(sandt > tar2){
    					 //应该让结果变小
    					 p2--;
    				 }else{
    					 p1++;
    				 }
    				 
    				 
    			 }
    			 
    		 }
    		 
    		 
    	 }
    	
    	 return res;
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值