【LeetCode】15. 三数之和(Set用法)
??今日学习的文章链接和视频链接
leetcode题目地址:15. 三数之和
?代码随想录题解地址:代码随想录
题目简介
给你一个整数数组?nums
?,判断是否存在三元组?[nums[i], nums[j], nums[k]]
?满足?i != j
、i != k
?且?j != k
?,同时还满足?nums[i] + nums[j] + nums[k] == 0
?。请
你返回所有和为?0
?且不重复的三元组。
注意:答案中不可以包含重复的三元组。
看到题目的第一想法(可以贴代码)
1. 最暴力的解法:对每个元素,求出它与其他所有元素的和,再判断剩余元素里是否contains其和的相反数;至于去重,可以将return的元素存成set,判断每次是否所有元素都在set里了。
? ? ? ? 写的好烂,出现各种小bug,甚至难以记录。? ? ? ? //超出时间限制
// 超出时间限制
public List<List<Integer>> threeSum(int[] nums) {
List<Integer> set = Arrays.stream(nums).boxed().collect(Collectors.toList());
List<List<Integer>> res = new ArrayList<>();
Set<Integer> check = new HashSet<>();
boolean c = false;
int count = 0;
for (int i : set){
if (i == 0) count++;
}
if(count >= 3) {
List<Integer> temp = new ArrayList<>();
temp.add(0);
temp.add(0);
temp.add(0);
res.add(temp);
}
for (int i = 0; i < nums.length; i++){
for (int j = i + 1; j < nums.length; j++){
set.remove(Integer.valueOf(nums[i]));
set.remove(Integer.valueOf(nums[j]));
if (set.contains(-(nums[i]+nums[j]))){
List<Integer> temp = new ArrayList<>();
temp.add(nums[i]);
temp.add(nums[j]);
temp.add(-(nums[i]+nums[j]));
for (List<Integer> lll : res){
if (lll.containsAll(temp)){
set.add(Integer.valueOf(nums[i]));
set.add(Integer.valueOf(nums[j]));
c = true;
continue;
}
}
if (c){
c = false;
continue;
}
res.add(temp);
}
set.add(Integer.valueOf(nums[i]));
set.add(Integer.valueOf(nums[j]));
}
}
return res;
}
实现过程中遇到哪些困难
1. List里add的Object,是一个指针?就是会随着Object后续的改变一起改变。
? ? ? ? 解决方案:在循环内每次new一个新的实例,每次添加的都是新的实例就行了。
2. 各种小bug....(好像是正常的)
看完代码随想录之后的想法
【解题思路】双指针法 + 排序(去重);就算用双指针法,好像也是用Map?
【想法】
1. 去重不能影响其他指针。
2. 主要还是逻辑没想清楚,建议下次拿出草稿纸好好想想再开始写代码。
看完视频自己写的ACC:
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
int left, right, sum = 0;
for (int i = 0; i < nums.length - 2; i++){
if (i > 0 && nums[i] == nums[i-1]) continue;
left = i + 1;
right = nums.length - 1;
while (left < right){
sum = nums[i] + nums[left] + nums[right];
if (sum == 0){
List<Integer> temp = new ArrayList<>();
temp.add(nums[i]);
temp.add(nums[left]);
temp.add(nums[right]);
res.add(temp);
while (left < right && nums[left] == nums[left+1]){
left++;
}
while (left < right && nums[right] == nums[right-1]){
right--;
}
left++;
right--;
}else if (sum < 0){
left++;
}else if (sum > 0){
right--;
}
}
}
return res;
}
?标答:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
// 找出a + b + c = 0
// a = nums[i], b = nums[left], c = nums[right]
for (int i = 0; i < nums.length; i++) {
// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if (nums[i] > 0) {
return result;
}
if (i > 0 && nums[i] == nums[i - 1]) { // 去重a
continue;
}
int left = i + 1;
int right = nums.length - 1;
while (right > left) {
int sum = nums[i] + nums[left] + nums[right];
if (sum > 0) {
right--;
} else if (sum < 0) {
left++;
} else {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
right--;
left++;
}
}
}
return result;
}
}
学习时长
9:00 ~ 12:00? 解题成功、看视频题解、写博客
今日收获
1.?实现Set的类
2. 双重数组/矩阵初始化
List<List<Integer>> list = new ArrayList<>();
不是:List<List<Integer>> res = new List<List<Integer>>();
3. Set用法
Set<Integer>转int[]
int[] arr = set.stream().mapToInt(Integer::intValue).toArray();
int[]转Set<Integer>
Integer[] arrInteger = Arrays.stream(arr).boxed().toArray(Integer[]::new);
Set<Integer> set = Arrays.stream(arrInteger).collect(Collectors.toSet());
-
add()?- 将指定的元素添加到集合中
-
addAll()?- 将指定集合的所有元素添加到集合中
-
iterator()?-返回一个迭代器,该迭代器可用于顺序访问集合中的元素
-
remove()?- 从集合中移除指定的元素
-
removeAll()?- 从存在于另一个指定集合中的集合中删除所有元素
-
keepAll()? -保留集合中所有还存在于另一个指定集合中的所有元素
-
clear()?- 从集合中删除所有元素
-
size()?- 返回集合的长度(元素数)
-
toArray()?- 返回包含集合中所有元素的数组
-
contains()?-? 如果集合包含指定的元素,则返回true
-
containsAll()?- 如果集合包含指定集合的所有元素,则返回true
-
hashCode()?-返回哈希码值(集合中元素的地址)
-
//基本的数学集合运算
-
Union?- 为了得到两个集合x和y的并集,我们可以使用x.addAll(y)
-
Intersection?- 要获得两个集合x和y的交集,我们可以使用x.retainAll(y)
-
Subset?- 要检查x是否是y的子集,我们可以使用y.containsAll(x)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!