• lintcode:三数之和


    题目

    给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。

    样例

    如S = {-1 0 1 2 -1 -4}, 你需要返回的三元组集合的是:

    (-1, 0, 1)

    (-1, -1, 2)

    注意

    在三元组(a, b, c),要求a <= b <= c。

    结果不能包含重复的三元组。

    解题:

    法一:直接暴力,时间复杂度是O(N3)

    public class Solution {
        /**
         * @param numbers : Give an array numbers of n integer
         * @return : Find all unique triplets in the array which gives the sum of zero.
         */
        public ArrayList<ArrayList<Integer>> threeSum(int[] numbers) {
            // write your code here
            
            ArrayList<ArrayList<Integer>>  result = new ArrayList<ArrayList<Integer>>();
            if(numbers == null || numbers.length<3)
                return result;
            for(int i = 0;i< numbers.length - 2 ; i++){
                ArrayList<Integer> path = new ArrayList<Integer>();
                for(int j = i+1;j < numbers.length - 1 ; j++){
                    for(int k = j+ 1 ; k < numbers.length ; k++)
                        if(numbers[i] + numbers[j] + numbers[k] == 0 ){
                            path = sort3(numbers[i],numbers[j],numbers[k]);
                            if(result.contains(path)==false)
                                result.add(path);
                        }
                }
            }
            return result;
        }
        public ArrayList<Integer> sort3(int a,int b,int c){
            ArrayList<Integer> path = new ArrayList<Integer>();
            if(a>b){
                int tmp = a;
                a = b;
                b = tmp;
            }
            if(c<=a){
                path.add(c);
                path.add(a);
                path.add(b);
            }else if(c>=b){
                path.add(a);
                path.add(b);
                path.add(c);
            }else{
                path.add(a);
                path.add(c);
                path.add(b);
            }
            return path;
            
        }
        
    }
    Java Code

    在运行到94%的测试数据的时候WA,下面答案只是第三个和第二个的顺序不一样,怎么能就算错了?

    法二:

    将原数组存放中ArrayList中,通过判断 -(nums[i]+nums[j]) 是否在ArrayList中,少了第三个for循环,时间复杂度O(N2)增加了空间发杂度O(N)

    public class Solution {
        /**
         * @param numbers : Give an array numbers of n integer
         * @return : Find all unique triplets in the array which gives the sum of zero.
         */
        public ArrayList<ArrayList<Integer>> threeSum(int[] numbers) {
            // write your code here
            ArrayList<Integer> path = new ArrayList<Integer>();
            ArrayList<ArrayList<Integer>>  result = new ArrayList<ArrayList<Integer>>();
            if(numbers == null || numbers.length<3)
                return result;
            ArrayList<Integer> nums = new ArrayList<Integer>();
            for(int i = 0 ;i < numbers.length ; i++)
                nums.add(numbers[i]);
            for(int i = 0;i< nums.size() - 2;i++){
                for(int j = i+ 1; j<nums.size() -1;j++){
                    int sum = -((Integer)nums.get(i) + (Integer)nums.get(j));
                    if(nums.contains(sum) && nums.indexOf(sum) !=j && nums.indexOf(sum) !=i){
                        path = sort3(sum,nums.get(i),nums.get(j));
                        if(result.contains(path)==false)
                            result.add(path);
                    }
                }
            }
            return result;
        }
        public ArrayList<Integer> sort3(int a,int b,int c){
            ArrayList<Integer> path = new ArrayList<Integer>();
            if(a>b){
                int tmp = a;
                a = b;
                b = tmp;
            }
            if(c<=a){
                path.add(c);
                path.add(a);
                path.add(b);
            }else if(c>=b){
                path.add(a);
                path.add(b);
                path.add(c);
            }else{
                path.add(a);
                path.add(c);
                path.add(b);
            }
            return path;
            
        }
        
    }
    Java Code

    但是运行还是出现上面的情况

    法三:

    三个数的和基础还是两个数的和两个数的和||,a+b+c = 0,等价于a+b = -c,这样就和两个数的和|| 很类似,当然也可以参考两个数的和I求解。

    先对数组排序,排序后的数组,定义其实节点i,然后对i+1 到len内的所有节点进行两端遍历,这里利用二分查找的思想,

    设两端的两个下标是left 和right ,显然 sum=nums[i] + nums[left] + nums[right] >0时候 ,right--,小于0的时候left++,等于0的时候就是答案。时间复杂度O(NlogN)

    public class Solution {
        /**
         * @param numbers : Give an array numbers of n integer
         * @return : Find all unique triplets in the array which gives the sum of zero.
         */
        public ArrayList<ArrayList<Integer>> threeSum(int[] numbers) {
            // write your code here
            
            ArrayList<ArrayList<Integer>>  result = new ArrayList<ArrayList<Integer>>();
            if(numbers == null || numbers.length<3)
                return result;
            Arrays.sort(numbers);
            for(int i = 0;i<numbers.length; i++){
                int left = i+ 1;
                int right = numbers.length - 1;
                while(left < right){
                    int sum = numbers[i] + numbers[left] + numbers[right];
                    ArrayList<Integer> path = new ArrayList<Integer>();
                    if(sum==0){
                        path.add(numbers[i]);
                        path.add(numbers[left]);
                        path.add(numbers[right]);
                        if(result.contains(path)==false)
                            result.add(path);
                        left++;
                        right--;
                    }else if(sum>0){
                        right--;
                    }else{
                        left++;
                    }
                }
            }
           
            return result;
        }
        
    }
    Java Code

    总耗时: 1094 ms

    class Solution:
        """
        @param numbersbers : Give an array numbersbers of n integer
        @return : Find all unique triplets in the array which gives the sum of zero.
        """
        def threeSum(self, numbers):
            # write your code here
            result = []
            if numbers == None or len(numbers) < 3:
                return result
            numbers.sort()
            numlen = len(numbers)
            for i in range(numlen):
                left = i + 1
                right = numlen - 1
                while left < right:
                    sum = numbers[i] + numbers[left] + numbers[right]
                    if sum==0:
                        path = [numbers[i],numbers[left],numbers[right]]
                        if path not in result:
                            result.append(path)
                        left +=1
                        right -=1
                    elif sum>0:
                        right -=1
                    else:
                        left +=1
                
            return result 
    Python Code

    总耗时: 195 ms

  • 相关阅读:
    典型用户与场景
    团队工作总结
    《构建之法》第8,9,10章
    冲刺1,2,3,4,5,天
    Github以及推广
    四则运算安卓版ver.mk3
    软件工程APP进度更新
    团队会议之事后工作总结
    构建之法 13-17章有感
    对于其他小组评论的反馈
  • 原文地址:https://www.cnblogs.com/theskulls/p/4912434.html
Copyright © 2020-2023  润新知