三数之和

162 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

前言

笔者除了大学时期选修过《算法设计与分析》和《数据结构》还是浑浑噩噩度过的(当时觉得和编程没多大关系),其他时间对算法接触也比较少,但是随着开发时间变长对一些底层代码/处理机制有所接触越发觉得算法的重要性,所以决定开始系统的学习(主要是刷力扣上的题目)和整理,也希望还没开始学习的人尽早开始。

系列文章收录《算法》专栏中。

力扣题目链接

问题描述

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

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

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

提示:

  • 0 <= nums.length <= 3000
  • -10^5 <= nums[i] <= 10^5

剖析

这道题和两数之和有点像,只不过现在是三数之和,同时需要得到所有的符合的三元数组,同时不能重复

所以我们可以对数组进行排序,如果发现和上一项相等的数字就直接跳过,然后利用双向指针进行移动,如果结果大于就把右指针往左移动,小于就继续遍历,等于就记录结果。

具体看代码。

代码

package com.study.algorithm.doublepointer;

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

public class ThreeSum {
    public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        int n = nums.length;
        //排好序 方便跳过重复的元素
        Arrays.sort(nums);
        for (int first = 0; first < n; first++) {
            //跳过重复的元素
            if (first > 0 && nums[first] == nums[first - 1]) {
                continue;
            }
            int thrid = n - 1;
            int target = -nums[first];
            for (int second = first + 1; second < n; second++) {
                //跳过重复的元素
                if (second > (first + 1) && nums[second] == nums[second - 1]) {
                    continue;
                }
                //大于的话就需要往左移动
                while (thrid > second && nums[second] + nums[thrid] > target) {
                    thrid--;
                }
                //重合的话就退出循环
                if (second == thrid) {
                    break;
                }
                if (nums[second] + nums[thrid] == target) {
                    List<Integer> resultChildren = new ArrayList<>();
                    resultChildren.add(nums[first]);
                    resultChildren.add(nums[second]);
                    resultChildren.add(nums[thrid]);
                    result.add(resultChildren);
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(threeSum(new int[]{-1, 0, 1, 2, -1, -4}));
    }
}