LeetCode 15 3Sum 找出数组里面3个数的和等于指定值。

题目:Given an arraySofnintegers, are there elementsa,b,cinSsuch thata+b+c= 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie,a≤b≤c)
  • The solution set must not contain duplicate triplets.

    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)
翻译: 给一个数组。找出其中3个数字等于0的组合。 按升序排列。

思路:这道题和前些天刷的Two Sum 原理差不多。只不过是Two Sum的和是前一个数字的相反数。还有一个问题就是,如果当前数字和下一个数字重复,应该排除这些重复,不遍历,减少复杂度。

代码:

public static ArrayList<ArrayList<Integer>> threeSum(int[] num)
	{
		ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
		if(num == null||num.length<3)//如果只有2个数字 或者为空 返回空
			return res;
		Arrays.sort(num);
		for(int i = 0; i<num.length -2;i++)// 保证最后得有num.length-1 和num.length-2两个数,才可以进循环
		{
			if(i > 0 && num[i] == num[i-1])//如果要是有重复的直接跳过。
				continue;
			ArrayList<ArrayList<Integer>> cur = twoSum(num,i+1,-num[i]); //得到当前数字可以组合出来的数字序列的子集。
			res.addAll(cur);
		}
		
		return res;        
    }
    public static ArrayList<ArrayList<Integer>>twoSum (int []num,int start,int target)
    {
    	
    	ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); 
    	if(num == null||num.length < 2)
    		return res;
    	int l = start;//起始位置
    	int pri = start-1;//当前数字
    	int r = num.length-1;//终止位置
    	while(l < r)//采用夹逼,逼近target
    	{
    		if(num[l]+num[r] == target)//
    		{
    			ArrayList<Integer> te = new ArrayList<Integer>();//符合的话 把三个数放入到list中
    			te.add(num[pri]);
    			te.add(num[l]);
    			te.add(num[r]);
    			res.add(te);
    			int k = l + 1;//从l的下一个开始 去除重复。
    			while(k < r&& num[k] == num[l])
    				k++;
    			l = k;
    			k = r - 1;//去除R的重复
    			while(k > l &&num[k] == num[r])
    				k--;
    			r = k;
    		}
    		else if(num[l] + num[r] > target)//夹逼
    			r--;
    		else l++;    	
    	}
    	
		return res;
    	
    }
如果要是求4 sum的话 直接可以在写个函数求出3 sum的 然后在整合到4sum中。原理其实差不多。

更好的办法,还有待考虑。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
给定一个整数数组 nums 和一个目标 target,要求在数组找出个数的和等于目标,并返回这两个数的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历数组的所有组合,判断两个数的和是否等于目标。如果等于目标,则返回这两个数的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储数组中的元素和对应的索引。遍历数组,对于每个元素nums[i],我们可以通过计算target - nums[i]的,查找哈希表中是否存在这个差。 如果存在,则说明找到了两个数的和等于目标,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果数组已经排序,可以使用双指针的方法来求解。假设数组从小到大排序,定义左指针left指向数组的第一个元素,右指针right指向数组的最后一个元素。 如果当前两个指针指向的数的和等于目标,则返回它们的索引。如果和小于目标,则将左指针右移一位,使得和增大;如果和大于目标,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个数的和等于目标或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果数组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果数组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值