今日学习的文章链接和视频链接
leetcode题目地址:第18题. 四数之和
代码随想录题解地址:代码随想录
题目简介
给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
看到题目的第一想法(可以贴代码)
1. 参考三数之和,排序+双重遍历+双元素+双指针(含去重)。
去重的逻辑我想不清楚:拿草稿纸慢慢想,写出来了。
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:
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. 代码风格:()和 {} 前后都要预留空格。