在一个数组中找到三元组,使得三元组内的三个元素加和为0。

这是一道Google面试题目,题目比较容易理解:

看例子:

Input : arr[] = {0, -1, 2, -3, 1}
Output : 0 -1 1
         2 -3 1

Input : arr[] = {1, -2, 1, 0, 5}
Output : 1 -2  1

其中一个最简单的想法就是3层循环,对数组进行遍历,找到加和等于0的三个元素,但是这个方法时间复杂度是 O(n3) ,所以想想能不能降低一下时间复杂度。

想到以前在Leetcode上做过一个3Sum的题目,这个题目跟现在这个题目的要求是相同的,那么我们可以这么做:

首先对数组进行排序,这样的话数组就是一个有序的数组了,这一步时间复杂度为 O(n2)

然后迭代选取数组中的元素,假设三个数字a,b,c。

for(int n : arr) {
    a = n;
}

现在我们要求a + b + c = 0,我们假设a = arr[i]那么我们可以让b = arr[i+1], c = arr[length - 1]

有了这个以后那就好办了,如果刚好a + b + c = 0,那就是我们要找的答案,插入到返回集合中就行。

如果a + b + c > 0,那么c就往前移动移动,让加和减小点;

当然如果a + b + c < 0,那么b就往后移动移动,让加和增大点;

就这么来回调整,直到找到答案或者遍历完数组。

这一段的时间复杂度也是 O(n2) ,那么两部分加起来的总时间复杂度还是 O(n2)

代码实现:

public class Solution {
    public List> threeSum(int[] nums) {
        List> list = new ArrayList<>();
        List numsList = new ArrayList<>();
        for (int i = 0; i < nums.length; i++)
            numsList.add(nums[i]);
        Collections.sort(numsList);

        int len = numsList.size();

        for (int i = 0; i < len - 2; i++){
            if (i > 0 && numsList.get(i - 1).equals(numsList.get(i)))
                continue;
            Integer a = numsList.get(i);
            int low = i + 1;
            int high = len - 1;

            while (low < high){
                Integer b = numsList.get(low);
                Integer c = numsList.get(high);

                if ((a + b + c) == 0){
                    List tl = new ArrayList<>();
                    tl.add(a);
                    tl.add(b);
                    tl.add(c);
                    list.add(tl);

                    while (low < len - 1 && numsList.get(low).equals(numsList.get(low + 1)))
                        low++;
                    while (high > 0 && numsList.get(high).equals(numsList.get(high - 1)))
                        high--;
                    low++;
                    high--;
                }else if ((a + b + c) > 0){
                    while (high > 0 && numsList.get(high).equals(numsList.get(high - 1)))
                        high--;
                    high--;
                }else{
                    while (low < len - 1 && numsList.get(low).equals(numsList.get(low + 1)))
                        low++;
                    low++;
                }
            }
        }
        return list;
    }
}

你可能感兴趣的:(Algorithm,Google,Interview,Array,面试题,谷歌,遍历,数组)