力扣18题解:四数之和(java实现)

力扣18题解:四数之和

引言

LeetCode上的第18题"四数之和"是一个中等难度的算法题目,要求找出数组中所有和为特定值的四元组。这个问题是"两数之和"和"三数之和"问题的扩展,考察了对哈希表和双指针技巧的运用。本文将通过Java语言实现这一算法,并提供详细分析。

题目描述

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出所有和为 target 的四元组 (nums[a], nums[b], nums[c], nums[d])(无序且 a < b < c < d),并返回这些四元组。

问题分析

这个问题可以通过嵌套三重循环来暴力解决,但时间复杂度会非常高(O(n^4))。更高效的方法是使用哈希表来存储元素和它们的索引,然后通过排除一些不可能的组合来减少不必要的计算。

算法设计

  1. 排序数组:首先对数组进行排序,以便于使用双指针技巧。
  2. 遍历数组 :遍历数组,对于每个元素 nums[i],尝试找到另外三个元素,使得它们的和等于 target - nums[i]
  3. 使用哈希表 :对于每个 nums[i],使用哈希表来存储 (target - 2 * nums[i], i + 1) 的映射,避免重复计算。
  4. 双指针 :对于每个 nums[i],使用双指针技巧在 i + 1 到数组末尾的范围内查找和为 target - nums[i] 的另外两个数。

Java实现

java 复制代码
 class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> list=new ArrayList<>();
        Arrays.sort(nums);
        
        for(int k=0;k<nums.length;k++){
            if(nums[k]>0&&nums[k]>target&&target>0){
                return list;
            }
            if(k>0&&nums[k]==nums[k-1]){
                continue;
            }
            for(int i=k+1;i<nums.length;i++){
                if((nums[i]+nums[k])>0&&(nums[i]+nums[k])>target&&target>0){
                    return list;
                }
                if(i>k+1&&nums[i]==nums[i-1]){
                    continue;
                }
                int left=i+1;
                int right=nums.length-1;
                while(right>left){
                    long sum=(long)nums[k]+nums[i]+nums[left]+nums[right];
                    if(sum>target){
                        right--;
                    }
                    else if(sum<target){
                        left++;
                    }
                    else{
                        list.add(Arrays.asList(nums[k],nums[i],nums[left],nums[right]));
                        while(right>left&&nums[right]==nums[right-1]) right--;
                        while(right>left&&nums[left]==nums[left+1]) left++;
                        right--;
                        left++;
                    }
                }
            }
        }
        return list;
    }
}
   

注意事项

  • 排序数组是为了使用双指针,同时方便跳过重复的元素。
  • 在使用双指针时,需要检查 leftright 索引的前一个元素是否与当前元素相同,以避免重复的四元组。
  • 需要检查 ij 的索引,避免索引越界。

结语

LeetCode第18题是一个经典的四数之和问题,通过这个问题,我们可以加深对哈希表和双指针技巧的理解。掌握这个问题的解法,对于解决其他类似问题非常有帮助。


相关推荐
Theodore_10222 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
冰帝海岸3 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象4 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了4 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·4 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王5 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康5 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神5 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式