新博文地址:
[leetcode]3Sum
http://oj.leetcode.com/problems/3sum/
Note:
Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4},
A solution set is:
(-1, 0, 1)
(-1, -1, 2)
这道题并没有想象中的那么简单.....+_+///最直观的想法肯定是三次遍历,算和,过滤,时间复杂度为O(n^3)压根就不用实现,肯定会超时。再一想:先排序,然后维护两个指针a,b,比如说a从0~ n - 2,b从1~n-1,然后根据二分查找,从b后面的数中找-a-b,时间复杂度为O(n*n*logN)我没实现,我觉得也肯定要TLE,后来手贱google了一下,惊奇的发现,原来rSum这个问题居然是 computational complexity theory中一个经典的问题,真是小看它了,绝逼的扮猪吃虎啊,其时间复杂度最小是O(n^2)
根据维奇百科中的解释,该题的一般解法有两种:
2 . Alternatively, the algorithm below first sorts the input array and then tests all possible pairs in a careful order that avoids the need to binary search for the pairs in the sorted list, again achieving O(n^2) time
第一种解法需要建hash表,我怕空间复杂度过大,就用的第二种,有兴趣的同学可以实现一下第一种方法。
第二种算法维护了三个指针,a,b,c。
-25 -10 -7 -3 2 4 8 10 (a+b+c==-22)
. . .
-25 -10 -7 -3 2 4 8 10 (a+b+c==-7)
-25 -10 -7 -3 2 4 8 10 (a+b+c==-7)
-25 -10 -7 -3 2 4 8 10 (a+b+c==-3)
-25 -10 -7 -3 2 4 8 10 (a+b+c==2)
-25 -10 -7 -3 2 4 8 10 (a+b+c==0)
其中a逐个往后遍历,b,c指针从a后面的数中找出满足条件的b和c,具体啥时候移动b啥时候移动c是很容易的。比较麻烦的一点是:如何过滤?
首先来看这组实例:
-4 -3 -2 0 1 2 3 4
首先我们把a指向-4,b指向-3,c指向4,容易发现-4 -3 + 4 < 0,因此希望值增大一点,需要移动b.
找到-4+0+4=0满足条件,这时候应该移动谁呢?答案是b,c皆可。因为需要找到下一个和为4 的两个数,两个指针都必须往中间移动,这里,我们约定,先移动b,再移动c。
如果我们往数组中插入几个数:-4 -3 -2 0 0 0 0 1 2 3 4
我们希望找到一直将b移动到与0不同的数,因此这里为了过滤,需要加一个判断。(标注1)
同理,这样插入几个数:-4 -4 -4 -4 -3 -2 0 1 2 3 4
就需要对a的移位进行判断,过滤掉已经处理过的数(标注2)
可能说的比较乱。还是看代码吧
public ArrayList<ArrayList<Integer>> threeSum(int[] num) { if (num == null || num.length < 3) { return new ArrayList<ArrayList<Integer>>(); } int length = num.length; ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); mergeSort(num, 0, length - 1); for(int i = 0; i <= length - 3; i++){ if(i > 0 && num[i] == num[i - 1]){(标注2) continue; } int a = i, b = i + 1,c = length -1; while(b < c){ if(num[a] + num[b] + num[c] == 0){ ArrayList<Integer> node = new ArrayList<Integer>(); node.add(num[a]); node.add(num[b]); node.add(num[c]); result.add(node); do{(标注1) b++; }while(num[b] == num[b - 1] && b < c); }else if(num[a] + num[b] + num[c] < 0){ b++; }else{ c--; } } } return result; }
其中的排序方法采取的是归并排序,代码如下:
private void mergeSort(int[] sum, int begin, int end) { if (sum == null || begin == end) { return; } int mid = (begin + end) / 2; mergeSort(sum, begin, mid); mergeSort(sum, mid + 1, end); merge(sum, begin, mid, end); } private void merge(int[] sum, int begin, int mid, int end) { int[] former = new int[mid - begin + 2]; int[] latter = new int[end - mid + 1]; for (int i = begin; i <= end; i++) { if (i <= mid) { former[i - begin] = sum[i]; if (i == mid) { former[mid - begin + 1] = Integer.MAX_VALUE; } } else { latter[i - mid - 1] = sum[i]; if (i == end) { latter[end - mid] = Integer.MAX_VALUE; } } } int index = begin; int formerIndex = 0, latterIndex = 0; while (index <= end) { sum[index++] = former[formerIndex] < latter[latterIndex] ? former[formerIndex++] : latter[latterIndex++]; } }
相关推荐
3sum 力码 力扣算法 (注:“ :locked: " 表示你需要来自 Leetcode) # 标题 解决方案 困难 001 简单的 002 中等的 003 中等的 004 难的 005 中等的 006 简单的 007 简单的 008 简单的 009 简单的 010 难的 011 中等...
3sum leetcode-curation-topical 精选 Leetcode 问题,按主题/概念分类。 我的策展标准是问题必须是有价值的,而不仅仅是为了难而难。 有价值的问题通常可以以不同的时间/空间效率(通过使用各种数据结构)以多种...
Leetcode two sum java 解法
本文将深入探讨如何使用Python实现双指针算法来解决LeetCode中的2sum、3sum和4sum问题,并提供相关代码示例。 首先,我们来看2sum问题。给定一个整数数组`nums`和一个目标值`target`,我们需要找到数组中两个数的...
本文档主要介绍了在Python编程语言中如何运用双指针算法解决LeetCode上的2Sum、3Sum及4Sum求和问题,并提供了相应的代码实现。LeetCode是一个非常受欢迎的在线编程平台,用于练习算法题目,尤其适合准备技术面试的...
3sum nlogn 让我们研究算法 微电脑网 : 2018.09.06。 用 BFS 搜索,用 DP 解决。 我过去没能做到,但感觉很好。 : 2018.09.06。 起初,它以这样的方式重复,如果有什么变化,它会再次旋转。 -> 超时 接下来,只将...
oj.leetcode题解, 2sum, 运用hashtable解决这到问题,时间复杂度O(N)
leetcode 2sum leetCode解决方案 我对 leetCode 问题的解决方案 已解决的练习列表: 简单的: ...3Sum - 效果不错,但仍需调整; O(n2) 复杂度; 花了~51ms 盛水最多的容器; O(n) 复杂度 难的: ?
3sum nlogn LeetCode 刷LeetCode题目思路 1.经典题目2SUM,利用hash_map完成 已知俩数之和,求能组成这个和的数字在数组中的下标 以数组中的值为key value,下标为value,即能实现常数级的复杂度 2.3Sum 题目同上,三...
3sum nlogn 编码问题 审查旧代码与早晨咖啡/茶搭配得很好;) Leetcode - DS & Alg : 链表,最小堆 : 二分查找 : 数组,动态规划 : 数组,Kadane 算法 : 树遍历 : 二叉树 : 二叉树 : 二叉树、队列、bfs : 字符串操作 ...
leetcode 2SUM 使用以前的地图最快的 2Sum O(N) 使用 unordered_map 比 map 快 以前的地图 là gì ? 上一张地图 đơn giản là 地图 nhưng thay vì ta cần một vòng for để khởi tạo 地图 thì ta khởi...
LC3: Longest Substring Without Repeating Characters [Medium] LC4: Longest Palindromic Substring [Medium] LC5: Median Of Two Sorted Arrays [Hard] LC6: Zigzag Conversion [Medium] LC7: Reverse Integer ...
3sum nlogn leetcode ny leetcode notebook time space c/c++ Time limite 1s - 2s data scale (n=* ) time complesity( O(*) ) example <=30 2^n expensial,dfs+cut 10^2 n^3 floyed 10^3 n^2, n^2*logn ...
java基础 leetcode java 题解之 3Sum With Multiplicity.java
3sum nlogn 面试准备 我在 LeetCode、AlgoExpert、Codewars、EPI book、Pramp、Codility 和其他面试准备资源上的编码面试问题的解决方案。 从 2020 年 10 月 20 日开始,我将每天将我的解决方案添加到此存储库中。 ...
3sum nlogn 力码 LeetCode 问题的解决方案。 尝试用所有语言解决它们。 地位 语言 构建状态 解决的问题 C C++ C# Java JavaScript Python Ruby 问题 # 标题 解决方案 时间 空间 注释 1 (4ms) (16ms) (496ms) (324ms...
3sum nlogn 标签: to-do list 书目评论 利特码攻占清朝 标题 我的时间复杂度 最佳时间复杂度 编程语言 日期 上) 上) Python 2020/02/29 上) 上) Python 2020/02/21 O(N^2) O(N^2) Python 2020/02/19 上) 上) ...
3sum nlogn 力码 LeetCode 问题的 JavaScript 解决方案。 问题 目录 问题 001-050 # 标题 解决方案 时间 空间 注释 1 二和 (72 毫秒) 上) 上) 2 两个数字相加 (260 毫秒) O(Max(N, M)) O(1) 3 无重复字符的最长...
3sum nlogn 话题 比赛 否 网站 问题 解决方案(Java) 解决方案(Python) 日期 1 力码 16-11-19 2 力码 —— 17-11-19 3 力码 —— 17-11-19 4 力码 —— 24-11-19 5 力码 —— 24-11-19 6 力码 —— 30-11-19 7 力码 ...
java入门 java_leetcode题解之015_3Sum