1. 程式人生 > >LeetCode 15題 : 給定一個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。

LeetCode 15題 : 給定一個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test15CorrectSolution {
    public static void main(String[] args) {
        /**
         * Leetcode第十五題:
         * 給定一個包含 n 個整數的陣列 nums,
         * 判斷 nums 中是否存在三個元素 a,b,c ,
         * 使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。
         * 
         * 解題思路: 定義兩個指標,將給定陣列nums重新排列後
         *         定義start為起始指標,end為結束指標,假設i為兩指標相加後的相反數
         *         for(int i = 0 ; i < nums.legth - 2){
         *         在其指標相間的數進行遍歷,其起始的值start=i+1
         *         if nums[start] + nums[end] == -nums[i] , List新增這組值,
         *         不然 如果 3個值的和大於0時,end--使其值降低
         *         其中如果nums[start]++==nums[start],則直接start++,end則是end--同理
         *         3值和小於0時,start++
         *          不然 start++,end-- ;直到 start指標 >= end指標後
         *          i++也要判斷是否重複值;
         *         }
         *         [ -4,-1,-1,0,1,2] [-2,0,0,2,2,]
         *         
         */
        int nums[] =  {-4,-2,1,-5,-4,-4,4,-2,0,4,0,-2,3,1,-5,0};
        List<List<Integer>> ends = threeSum(nums);
        for(List<Integer> i : ends){
            System.out.println(i);
        }
    }
    
    public static List<List<Integer>> threeSum(int[] nums) {
        //先給定的陣列重排序
        Arrays.sort(nums);
        List<List<Integer>> allList = new ArrayList<List<Integer>>();
        //假設i為start指標與end指標的和
        for(int i = 0 ; i < nums.length - 2;){
           //start指標對應起始位置
            int start = i + 1;
            //end指標對應結束位置
            int end = nums.length - 1;
            while(start < end ){
                if(nums[start] + nums[end] == -nums[i]){
                    List<Integer> list = new ArrayList<>(3);
                    list.add(nums[i]);
                    list.add(nums[start]);
                    list.add(nums[end]);
                    allList.add(list);
                    start++;
                    end--;
                    //除去end指標的重複值
                    while(nums[end] == nums[end+1] && start < end){
                        end--;
                    }
                    //除去start指標的重複值
                    while(nums[start] == nums[start-1] && start < end){
                        start++;
                    }
                }
                //3值的和大於0時,重新檢測end指標是否重複後降值
                else if(nums[start] + nums[end] > -nums[i] ){
                    end--; 
                    while(nums[end] == nums[end+1] && start < end){
                        end--;
                    }
                }
                //3值的和小於0時,重新檢測start指標是否重複後升值
                else{
                    start++;
                    while(nums[start] == nums[start-1] && start < end){
                        start++;
                    }
                }
            }
            
            i++;
            while(nums[i] == nums[i-1] && i < nums.length - 2){
                i++;
            }
        }
        return allList;
    }

}