题目
就是三数之和,跟LeetCode不一样的地方在于不是求和等于0而是改成了指定的target,有一说一题不难;
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = target ?请你找出所有和为 target 且不重复的三元组。 注意:答案中不可以包含重复的三元组。
思路
15. 三数之和LeetCode_加油当当的博客-CSDN博客
要注意的就是需要自己特殊练习一下 有输入输出的,不然LeetCode刷管了还是有点不适应的;
- 为了不重复,需要进行排序
- 第二个数和第三个数的寻找可以通过使用双指针,一个从先往后,另一个当两数之和大于目标-第一个数的时候,从后往前进行寻找(因为总和一定,一个数大,另一个数必然减小),这样节省了一个循环呢!第三个数一定比第二个数大,否则也不会存在了!
- 不同中最经典的情况就是0,0,0,0,0了,这结果只能是000,而不从五个零中任意取出3个零,所以要保证,每次选取的数字都是不同的
- 严格意义上来说,这个保证每个元素不相同是在存入到输出的集合之后保证的或已经有一个数的前提下才行,如果一开始就保证,那么当0,0,0,0,0就一般是错误的解(类似的错误还有很多),所以first是大于0而不是从0开始,second也是从first+2开始,这些都是为了保证起码有一个数,不然可能就直接没了。
- 其实压入之前去重和压入之后去重都一样,只不过,压入之前去重需要保证至少有一个会压入(也就是不从头开始,从第二个开始);而压入之后去重则没有这么多考虑,或者说,这其实与循环有关,本身用for进行循环的时候,用if搞去重,没有for之后就得自己想办法去重,自然形式也不一样,也就不用苛求用同一种方法进行去重
-
// 只是用first举个例子,其实是三个都需要保证取的下一个元素是不重复的 if (first > 0 && nums[first] == nums[first - 1]) { continue; } if (second > first + 1 && nums[second] == nums[second - 1]) { continue; }
- 当第二个数与第三个数相等的时候,结束。?
代码
import java.util.*;
class Solution {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<List<Integer>> res = threeSum(arr, 16);
for (int i = 0; i < res.size(); i++) {
for (int j = 0; j < res.get(i).size(); j++) {
System.out.print(res.get(i).get(j) + " ");
}
System.out.println();
}
}
public static List<List<Integer>> threeSum(int[] nums, int target) {
int n = nums.length;
Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<>();
for (int first = 0; first < n; first++) {
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
int second = first + 1;
int third = n - 1;
while (second < third) {
int sum = nums[first] + nums[second] + nums[third];
if (sum > target) {
third--;
} else if (sum < target) {
second++;
} else {
List<Integer> list = new ArrayList<>();
list.add(nums[first]);
list.add(nums[second]);
list.add(nums[third]);
ans.add(list);
while (second < third && nums[second] == nums[second + 1]) second++;
while (second < third && nums[third] == nums[third - 1]) third--;
second++;
third--;
}
}
}
return ans;
}
}
心得体会
快手两面给我的感觉就是面试官人很好,题目问的也不是很难的那种,都是常规的题目,希望能通过面试,如果没通过面试,也会为我今后的学习生活提供一定的指导;
祝好!
|