LeetCode第15题,难度中等,题目描述:java
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出全部知足条件且不重复的三元组。git
注意:答案中不能够包含重复的三元组。github
什么也无论先来个O(n3):算法
for(int i=0;i<nums.length;++i) { for(int j=i+1;j<nums.length;++j) { for(int k=j+1;k<nums.length;++k) { if(nums[i]+nums[j]+nums[k] == 0) { ArrayList<Integer> arrayList = new ArrayList<>(); arrayList.add(nums[i]); arrayList.add(nums[j]); arrayList.add(nums[k]); result.add(arrayList); } } } }
well.数组
上面暴力算法的思想就是单纯三个循环,优化的方法能够考虑下降一个循环,使用"双指针"的思想,首先对数组进行排序,而后一开始固定一个数,而后让两个指针一个指向这个数的右区间的起点,一个指向终点,不断计算这三个值的和,根据得出的和移动左指针或者右指针,一共三种状况:优化
基于以上的三种状况,写出了以下代码:指针
List<List<Integer>> result = new ArrayList<>(); if (nums.length == 3 && nums[0] + nums[1] + nums[2] == 0) result.add(Arrays.asList(nums[0], nums[1], nums[2])); else if (nums.length > 3) { Arrays.sort(nums); Set<List<Integer>> resultSet = new HashSet<>(); for (int i = 0; i < nums.length - 2 && nums[i] <= 0; ++i) { int left = i + 1; int right = nums.length - 1; while (left < right) { int sum = nums[i] + nums[left] + nums[right]; if (sum == 0) { if (!resultSet.contains(Arrays.asList(nums[i], nums[left], nums[right]))) resultSet.add(Arrays.asList(nums[i], nums[left], nums[right])); --right; ++left; } else if (sum > 0) --right; else ++left; } } result.addAll(resultSet); }
首先判断数组的长度是否大于等于3,小于3的话直接返回一个空List,等于3判断是否这三个数之和为0,大于3的话,首先排序,接着须要确保被肯定的相对不移动的数为负数,这样的话剩下两个数的和才有可能为正数,不然的话会形成所有都是正数还要进行判断的局面.接着计算left指针与right指针的值,一直判断直到两指针相遇.code
AC!blog
github排序