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


相关推荐
qiuiuiu4139 小时前
CPrimer Plus第十六章C预处理器和C库总结2-qsort函数
java·c语言·算法
IT学长编程10 小时前
计算机毕设选题 基于SpringBoot的书店管理系统的设计与实现 网上书店系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·前后端分离·网上书店系统·书店管理系统
张较瘦_10 小时前
应用型本科计算机类专业毕业设计与论文选题指南
java·开发语言·课程设计
IT学长编程10 小时前
计算机毕设选题 基于SpringBoot的房产租赁管理系统 房屋租赁系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·房屋租赁系统·房产租赁系统·文档报告
JuneXcy10 小时前
C++知识点总结用于打算法
c++·算法·图论
木易 士心11 小时前
MPAndroidChart 用法解析和性能优化 - Kotlin & Java 双版本
android·java·kotlin
后端小张11 小时前
SpringBoot 控制台秒变炫彩特效,秀翻同事指南!
java·后端
好家伙VCC12 小时前
**标题:发散创新:探索AR开发框架的核心技术**随着增强现实(AR)技术的飞速发展,AR开发框架成为了开发者们关注的焦
java·ar
zhuzhuxia⌓‿⌓12 小时前
线性表的顺序和链式存储
数据结构·c++·算法
chools12 小时前
学习问题日记-4
java