题目描述:

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

题目解析:

首先对数组进行排序(时间复杂度O(nlog(n))),排序后固定一个数 nums[i],再使用左右指针指向 nums[i]后面的两端,数字分别为 nums[L] 和 nums[R],计算三个数的和 sum 判断是否满足为 0,满足则添加进结果集
如果 nums[i]大于 0,则三数之和必然无法等于 0,结束循环
如果 nums[i] == nums[i-1],则说明该数字重复,会导致结果重复,所以应该跳过
当 sum == 0时,nums[L] == nums[L+1] 则会导致结果重复,应该跳过,L++
当 sum0 时,nums[R] = nums[R-1] 则会导致结果重复,应该跳过,R--
时间复杂度:O(n^2),n 为数组长度

代码实现:

package com.company;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class Main { public static void main(String[] args) {
int[] nums = new int[]{-1, 0, 1, 2, -1, -4};
System.out.println(threeSum(nums));
} private static List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length < 3) {
return result;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) {
break;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;
int rigth = nums.length - 1;
while (left < rigth) {
int sum = nums[left] + nums[rigth] + nums[i];
if (sum == 0) {
result.add(Arrays.asList(nums[i], nums[left], nums[rigth]));
while (left < rigth && nums[left] == nums[left + 1]) {
left++;
}
while (left < rigth && nums[rigth] == nums[rigth - 1]) {
rigth--;
}
left++;
rigth--;
} else if (sum < 0) {
left++;
} else {
rigth--;
}
} }
return result;
}
}

时间复杂度:O(n^2),n 为数组长度

空间复杂度:O(1),常数空间存储

最新文章

  1. JS三大特性
  2. 双向链表、双向循环链表的JS实现
  3. Sring控制反转(Inversion of Control,Ioc)也被称为依赖注入(Dependency Injection,DI)原理用反射和代理实现
  4. transform scale 背景图片模糊怎么办?
  5. 【未解决】eclipse未自动引入maven依赖
  6. apiCloud中图片裁剪模块FNImageClip的使用
  7. 值栈与ognl
  8. 怎样绕过oracle listener 监听的password设置
  9. 201521123039 《java程序设计》第九周学习总结
  10. golang的GET请求(类似于PHP的CURL)
  11. return *this 与return this的区别
  12. hive编程指南——读书笔记(无知拾遗)
  13. APP网站安全漏洞检测服务的详细介绍
  14. android 2018 面试题
  15. Oracle高级查询之over(partition by...)
  16. Vue中添加新的路由并访问
  17. WPF:Metro样式ProgressBar(圆点横向移动),自适应宽度
  18. WPF(C#)与MATLAB混合编程
  19. 在java中为什么要把main方法定义为一个static方法?
  20. cocos2d-x 日志...

热门文章

  1. docker基础知识
  2. CSS选择器(通配符选择器、标签选择器、类选择器、id选择器、群组选择器、后代选择器、子元素选择器和相邻元素选择器)
  3. openlayers加载天地图过程中遇到跨域问题
  4. JavaJDBC【二、Mysql包加载与使用】
  5. Linux :ssh sftp scp
  6. Tomcat7设置环境变量供java代码读取
  7. java线程基础巩固---多线程下的生产者消费者模型,以及详细介绍notifyAll方法
  8. 搭建单机版伪分布zookeeper集群
  9. vue.js 简介
  10. vue插件——滚动监听 vue-scrollwatch