【LeetCode】第18题. 四数之和

今日学习的文章链接和视频链接

leetcode题目地址:第18题. 四数之和

代码随想录题解地址:代码随想录

题目简介

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复 的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abcd 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

看到题目的第一想法(可以贴代码)

  1. 参考三数之和,排序+双重遍历+双元素+双指针(含去重)。

去重的逻辑我想不清楚:拿草稿纸慢慢想,写出来了。

java 复制代码
public List<List<Integer>> fourSum(int[] nums, int target) {
    Arrays.sort(nums);
    int len = nums.length;
    int sum = 0;
    int left = 0, right = 0;
    List<List<Integer>> res = new ArrayList<>();
    for (int i = 0; i < len - 3; i++){
        if (i > 0 && nums[i] == nums[i - 1]) continue;
        for (int j = i + 1; j < len - 2; j++){
            left = j + 1;
            right = len - 1;
            while (left < right){
                sum = nums[i] + nums[j] + nums[left] + nums[right];
                if (sum == -294967297 ||sum == -294967296) return res;
                if (sum == target){
                    res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                    while (left < right && nums[left] == nums[left + 1]) left++;
                    while (left < right && nums[right] == nums[right - 1]) right--;
                    left++;
                    right--;
                    if (nums[left - 1] == nums[j]){
                        while (j < len - 2 && nums[j] == nums[j + 1]) j++;
                        j--;
                    }else {
                        while (j < len - 2 && nums[j] == nums[j + 1]) j++;
                    }
                }else if (sum < target){
                    left++;
                }else if (sum > target){
                    right--;
                }
            }
        }
    }
    return res;
}

实现过程中遇到哪些困难

  1. int类型最大值和最小值分别为2147483647, -2147483648;如果超出最大值会变为-294967297和 -294967296,不太懂它的原理,要不是补码,要不是力扣自定义。

看完代码随想录之后的想法

【解题思路】参考三数之和,二重剪枝+二重去重。

【想法】

  1. 关于超出int的表示范围:可以将sum设为long类型,同时sum赋值前也要加(long),强制转换

  2. 关于我思考的-1,-1,-1,3和-1,-1,0,2,前两个数两次取-1,-1的情况,可以在底下的while里实现。

  3. 两次剪枝,我直接省略了。

看完视频自己写的ACC:

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

学习时长

碎片化,不记录


今日收获

  1. 变量定义不要放在最前面,哪里用得到就在哪里定义,重复定义了也没事。。?

  2. 代码风格:()和 {} 前后都要预留空格。

相关推荐
Hello.Reader5 小时前
算法基础(十)——分治思想把大问题拆成小问题
java·开发语言·算法
逻辑驱动的ken6 小时前
Java高频考点场景题24
java·开发语言·面试·职场和发展·求职招聘
绛橘色的日落(。・∀・)ノ6 小时前
机器学习之评估与偏差方差分析
算法
消失的旧时光-19436 小时前
C语言对象模型系列(四)《Linux 内核里的 container_of 到底是什么黑魔法?》—— 一篇讲透 Linux 内核的“对象模型”核心技巧
linux·c语言·算法
AI_Ming7 小时前
从0开始学AI:层归一化,原来是这回事!
算法·ai编程
WL_Aurora7 小时前
备战蓝桥杯国赛【Day 8】
算法·蓝桥杯
智者知已应修善业7 小时前
【51单片机模拟生日蜡烛】2023-10-10
c++·经验分享·笔记·算法·51单片机
MediaTea7 小时前
Scikit-learn:从数据到结构——无监督学习的最小闭环
人工智能·学习·算法·机器学习·scikit-learn
智者知已应修善业7 小时前
【51单片机如何让LED灯从一亮到八,再从八亮到一】2023-10-13
c++·经验分享·笔记·算法·51单片机
qeen877 小时前
【数据结构】二叉树相关经典函数C语言实现
c语言·数据结构·c++·笔记·学习·算法·二叉树