三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
package com.cjh.leetcode;

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

import com.sun.jndi.url.corbaname.corbanameURLContextFactory;
import com.sun.swing.internal.plaf.basic.resources.basic;

import sun.util.logging.resources.logging;

public class A6 {
	public static void main(String[] args) {
		int[] nums = {-1,0,1,2,-1,-4};
		System.out.println(threeSum1(nums));
	}
	
	public static List<List<Integer>> threeSum(int[] nums) {
        //判断是否存在三元组 
		//[nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,
		//同时还满足 nums[i] + nums[j] + nums[k] == 0 。
		ArrayList<List<Integer>> arrayList = new ArrayList<List<Integer>>();
		//先对数组进行排序,这样相同的元素就能相邻了
		Arrays.sort(nums);
		
		for (int i = 0; i < nums.length - 2; i++) {
			// 跳过重复的i值,避免重复三元组
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
			for (int j = i+1; j < nums.length - 1; j++) {
				if (j > i + 1 && nums[j] == nums[j - 1]) {
					continue;
				}
				for (int k = j+1; k < nums.length; k++) {
					if (k > j + 1 && nums[k] == nums[k - 1]) {
						continue;
					}
					if (nums[i] + nums[j] + nums[k] == 0) {
						ArrayList<Integer> list = new ArrayList<>();
						list.add(nums[i]);
						list.add(nums[j]);
						list.add(nums[k]);
						arrayList.add(list);
					}
				}
			}
		}
		return arrayList;
    }
	
	 public static List<List<Integer>> threeSum1(int[] nums) {
		 	//对数组元素进行排序
	        Arrays.sort(nums);
	        ArrayList<List<Integer>> list = new ArrayList<>();
	        //枚举a
	        for (int i = 0; i < nums.length; i++) {
	        	//跳过相同的元素
				if (i > 0 && nums[i] == nums[i-1]) {
					continue;
				}
				//每次枚举a时都要初始化指针c和目标值-> a+b+c -> b+c=-a
				int k = nums.length - 1;
				int target = -nums[i];
				//枚举b
				for (int j = i + 1; j < nums.length; j++) {
					//跳过相同的元素
					if (j > i + 1 && nums[j] == nums[j-1]) {
						continue;
					}
					//当k指针在j右侧时,且b+c>target,说明k需要向左移动
					while(j < k && nums[j] + nums[k] > target) {
						k--;
					}
					//如果两指针都相遇了,说明没找到,跳出循环
					if (j == k) {
						break;
					}
					if (nums[j] + nums[k] == target) {
						ArrayList<Integer> list2 = new ArrayList<>();
						list2.add(nums[i]);
						list2.add(nums[j]);
						list2.add(nums[k]);
						list.add(list2);
					}
				}
				
			}
	        
	        return list;
	    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值