力扣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题是一个经典的四数之和问题,通过这个问题,我们可以加深对哈希表和双指针技巧的理解。掌握这个问题的解法,对于解决其他类似问题非常有帮助。


相关推荐
PAK向日葵4 小时前
【算法导论】PDD 0817笔试题题解
算法·面试
桦说编程6 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
lifallen6 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研6 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
地平线开发者6 小时前
ReID/OSNet 算法模型量化转换实践
算法·自动驾驶
地平线开发者7 小时前
开发者说|EmbodiedGen:为具身智能打造可交互3D世界生成引擎
算法·自动驾驶
没有bug.的程序员7 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋7 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
星星火柴9368 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
阿华的代码王国8 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端