15. 三数之和-字节跳动高频题

Posted hequnwang10

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了15. 三数之和-字节跳动高频题相关的知识,希望对你有一定的参考价值。

一、题目描述

给你一个包含 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]
输出:[]

二、解题

排序+两数之和+双指针

排序之后,两数之和可以使用双指针实现。所以这题就是在两数之和的基础上的延伸。

class Solution 
    public List<List<Integer>> threeSum(int[] nums) 
        //排序 + 双指针
        int length = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        for(int first = 0;first<length;first++)
            //特殊判断 如果第一个数大于0 直接返回,或者这一个数与前一个数相同,跳过去重
            if(first>0 && nums[first] == nums[first - 1])
                continue;
            
            //使用双指针指向下一个元素和最右端元素
            int third = length - 1;
            //直接转换为两数之和问题
            int target = -nums[first];
            for(int second = first + 1;second<length;second++)
                //去重
                if(second > first + 1 && nums[second] == nums[second - 1])
                    continue;
                
                //双指针遍历
                while(second < third && nums[second] + nums[third] > target)
                    third--;
                
                //如果指针重合中断循环
                if(second == third)
                    break;
                
                if(nums[second] + nums[third] == target)
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[third]);
                    res.add(list);
                

            
        
        return res;
    

class Solution 
    public List<List<Integer>> threeSum(int[] nums) 
        //排序+双指针
        List<List<Integer>> res = new ArrayList<>();
        int length = nums.length;
        //排序
        Arrays.sort(nums);
        //双指针
        for(int i = 0;i<length;i++)
            //若大于0直接退出
            if(nums[i] > 0)
                break;
            
            //去重
            if(i>0 && nums[i]==nums[i-1])
                continue;
            
            int target = -nums[i];
            int left = i+1;
            int right = length-1;
            //在[left,right]中查找两数之和是否等于target,并且去重
            while(left<right)
                int sum = nums[left]+nums[right];
                if(sum == target)
                    //添加数据
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    res.add(list);
                    //进行下一轮的循环前,先去重
                    while(left<right && nums[left]==nums[left+1])
                        left++;
                    
                    while(left<right && nums[right] == nums[right-1])
                        right--;
                    
                    //添加数据了,说明首尾两个数据可以组成三元组,则继续判断[left+1,right-1];
                    left++;
                    right--;
                else if(sum<target)
                    left++;
                else
                    right--;
                

            
        
        return res;
    

以上是关于15. 三数之和-字节跳动高频题的主要内容,如果未能解决你的问题,请参考以下文章

字节跳动高频算法题TOP100

字节跳动高频算法题TOP100

1. 两数之和-字节跳动高频题

56. 合并区间-字节跳动高频题

leetcode 每日一题 15. 三数之和

105. 从前序与中序遍历序列构造二叉树-字节跳动高频题