LeetCode 三数之和 — 优化解法
LeetCode 三数之和 — 改进解法
题目:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[ [-1, 0, 1], [-1, -1, 2] ]
最开始做的解法是先将整个数组排序;然后遍历前两个数(a和b)的所有情况(n^2);对于第三个数,则从剩余的数中(即从第二个数下一个位置开始到末尾)利用二分查找出是否存在数字 -(a+b)即可。 复杂度O(n^2·logn) :
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Arrays.sort(nums);
Map<Integer,Integer> mi = new HashMap();
for(int i=0;i<nums.length-1;i++) {
if(mi.get(nums[i]) != null) continue; //记录i下标读过的数字
mi.put(nums[i],1);
Map<Integer,Integer> mj = new HashMap();
for(int j=i+1;j<nums.length;j++) {
if(mj.get(nums[j]) != null) continue; //记录j下标读过的数字
mj.put(nums[j],1);
int temp = -(nums[i]+nums[j]);
if(bSearch(nums,j+1,nums.length-1,temp) == false) continue; //二分搜索j下标之后的区间是否有数字temp
ans.add(Arrays.asList(nums[i],nums[j],temp));
}
}
return ans;
}
//二分算法
public boolean bSearch(int[] nums,int s,int e,int key) {
int start=s,end=e,mid;
while(start<=end){
mid = (start+end)/2;
if(key < nums[mid]) end=mid-1;
else if(key > nums[mid]) start=mid+1;
else if(key == nums[mid]) return true;
}
return false;
}
}
里面有两个用了哈希的地方,所以时间复杂度应该还要乘上一个常数K...(解数组相关的题感觉总有些依赖哈希的方法=_= ...)
最近做了另一个数组区间相关的题目,受其解法的启发,打算对这道题解法进行优化。
还是先对数组进行排序;对第一个数字(a)进行遍历,而然后在剩余的数中用前后指针的方法找出两个和为-a的数字:两个指针left和right;left初始化为数字a的下一位置,right为最后一个位置。比较nums[left]+nums[right]+a和0的大小;如果大于0则right--,小于就left++。 其中在添加结果集时需考虑去重问题,用个哈希判断是否有重复就行了,复杂度O(n^2·K) :
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Arrays.sort(nums);
Map<Integer,Integer> mi = new HashMap();
for(int i=0;i<nums.length-2;i++) {
if(mi.get(nums[i]) != null) continue; //记录i下标读过的数字
mi.put(nums[i],1);
Map<Integer,Integer> mj = new HashMap();
int l = i+1, r = nums.length-1, temp;
while(l<r) {
temp = nums[i] + nums[l] + nums[r];
if(temp < 0) {
l++;
} else if(temp > 0) {
r--;
} else {
if((mj.get(nums[l])) == null) {
ans.add(Arrays.asList(nums[i], nums[l], nums[r]));
mj.put(nums[l], 1);
}
l++; r--;
}
}
}
return ans;
}
}
LeetCode 三数之和 — 优化解法的更多相关文章
- [leetcode]三数之和
三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复 ...
- [LeetCode] 3Sum Closest 最近三数之和
Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...
- [LeetCode] 3Sum 三数之和
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...
- [LeetCode] 923. 3Sum With Multiplicity 三数之和的多种情况
Given an integer array A, and an integer target, return the number of tuples i, j, k such that i &l ...
- [LeetCode] 16. 3Sum Closest 最近三数之和
Given an array nums of n integers and an integer target, find three integers in nums such that the s ...
- [LeetCode] 15. 3Sum 三数之和
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...
- LeetCode:两数之和、三数之和、四数之和
LeetCode:两数之和.三数之和.四数之和 多数之和问题,利用哈希集合减少时间复杂度以及多指针收缩窗口的巧妙解法 No.1 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在 ...
- [LeetCode] 3Sum Smaller 三数之和较小值
Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 < ...
- LeetCode(15):三数之和
Medium! 题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答 ...
随机推荐
- MaskRCNN:三大基础结构DeepMask、SharpMask、MultiPathNet
MaskXRCnn俨然成为一个现阶段最成功的图像检测分割网络,关于MaskXRCnn的介绍,需要从MaskRCNN看起. 当然一个煽情的介绍可见:何恺明团队推出Mask^X R-CNN,将实例分割扩展 ...
- 三维重建PCL:点云单侧面正射投影
终于把点云单侧面投影正射投影的代码写完了,为一个阶段,主要使用平面插值方法,且只以XOY平面作为的正射投影面.有些凑合的地方,待改进. 方法思路:使用Mesh模型,对每一个表面进行表面重建.借助Ope ...
- 字符编码方式ASCII、Unicode、UTF-8
一.ASCII 1.介绍 即American Standard Code for Information Interchange(美国信息交换标准代码),是基于拉丁字母的,主要用于显示现代英语和其他西 ...
- Android(java)学习笔记204:JNI之native方法头文件的生成
1. JDK1.6 ,进入到工程的bin目录下classes目录下: 使用命令: javah packageName.ClassName 会在当前目录下生成头文件,从头文件找到jni协议方法 下面举 ...
- SDK_进度条和滑块
进度条和滑块 进度条和滑块属于通用控件,通用控件的使用需要加 CommCtrl.h 头文件 如何初始化进度条和滑块的数值范围和默认的位置 // 设置默认的范围值SendDlgItemMessage(h ...
- java_线程创建的两种方法
线程创建的方法有两种: 一 继承Thread类: public class ThreadTest { public static void main(String[] args) { //4)在mai ...
- oracle 安装准备
1.选择数据库 (官网查询支持的操作系统) 2.选择系统 (官网查询支持的硬件)(更新补丁) 3.选择硬件 (io性能测试--oracle 大量小文件读写) 4.oracle 升级(和打补丁) 5.o ...
- 学习笔记7——使用Scanner获取键盘输入
使用Scanner类可以很方面地获取用户的键盘输入,Scanner是一个基于正则表达式的文本扫描器,它可以从文件.输入流.字符串中解析出基本类型值和字符串值.Scanner类提供了多个构造器,不同的构 ...
- 【实验级】Docker-Compose搭建单服务器ELK伪集群
本文说明 由于最近在搭ELK的日志系统,为了演示方案搭了个单台服务器的日志系统,就是前一篇文章中所记,其实这些笔记已经整理好久了,一直在解决各种问题就没有发出来.在演示过程中我提到了两个方案,其中之一 ...
- oracle 内连接 左外连接 右外连接的用法,(+)符号用法
1. 内连接很简单 select A.*, B.* from A,B where A.id = B.id select A.*, B.* from A inner join B on A.id = B ...