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


相关推荐
七颗糖很甜2 分钟前
基于 OpenCV 的 FY2 云顶图云块追踪算法实现
人工智能·opencv·算法
__Wedream__3 分钟前
NTIRE 2026 Challenge on Efficient Super-Resolution——冠军方案解读
人工智能·深度学习·算法·计算机视觉·超分辨率重建
FL16238631297 分钟前
基于深度学习mediape实现人员跌倒人体姿势跌倒检测算法源码+说明文件
人工智能·深度学习·算法
wangwangmoon_light8 分钟前
1.23 LeetCode总结(树)_一般树
算法·leetcode·职场和发展
若水不如远方9 分钟前
一文讲透单点登录原理(SSO):从同域共享到跨域票据
java·后端
不懂的浪漫9 分钟前
mqtt-plus 架构解析(七):动态订阅与重连恢复,为什么能走同一条协调路径
java·物联网·mqtt·架构
被考核重击10 分钟前
基础算法学习
学习·算法
无巧不成书021812 分钟前
Unicode编码机制全解析:从核心原理到Java 实战
java·开发语言·java字符编码·unicode 15.1码点
小O的算法实验室12 分钟前
2026年ASOC,学习驱动人工蜂群算法+移动机器人多目标路径规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
mu_guang_16 分钟前
计算机体系结构3-cache一致性和内存一致性的区别
java·开发语言·计算机体系结构