力扣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实现

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


  • 21
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值