leetcode-15-三数之和

问题:

 解:

class Solution {
     /**
     * 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?
     * 找出所有满足条件且不重复的三元组。
     * 双指针法,
     * 首先,将数组nums排序,循环整个数组
     * 在num[i]后定义左右两个指正,left=i+1,right=len-1
     * 1)如果nums[i] 大于零的话,那么三个数相加一定大于0,终止循环,
     * 2)如果nums[i] == nums[i - 1],则代表该值已经判断过,跳过该值
     * 3)当三个数和等于0时,如果nums[left] == nums[left + 1],会导致数据重复,跳过该值,记录右侧的值为结果
     * 4)当三个数和等于0时,如果nums[right] == nums[right - 1],会导致数据重复,跳过该值,记录左侧的值为结果
     *
     * @param nums
     * @return
     */
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if (nums == null || nums.length < 3) {
            return res;
        }
        //先将数组排序
        quickSort(nums, 0, nums.length - 1);
        // 双指针法
        for (int i = 0; i < nums.length && nums[i] <= 0; i++) {
            int left = i + 1;
            int right = nums.length - 1;
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum == 0) {
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    res.add(list);
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }
                    left++;
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    right--;
                }
            }
        }

        return res;
    }
    
        /**
     * 快排nums数组
     *
     * @param arr
     * @param left
     * @param right
     * @return
     */
    public void quickSort(int[] arr, int left, int right) {
        //递归终止条件
        if (left > right) {
            return;
        }

        int base = arr[left];
        int l = left;
        int r = right;
        while (l != r) {
            while (l < r && arr[r] >= base) {
                r--;
            }
            while (l < r && arr[l] <= base) {
                l++;
            }
            if (l < r) {
                swap(arr, r, l);
            }
        }
        swap(arr, left, l);

        quickSort(arr, left, l - 1);
        quickSort(arr, l + 1, right);
    }

    /**
     * 交换两个数
     *
     * @param arr
     * @param r
     * @param l
     */
    private void swap(int[] arr, int r, int l) {
        int temp = arr[r];
        arr[r] = arr[l];
        arr[l] = temp;
    }
}

 

posted @ 2019-07-28 00:45  xj-record  阅读(103)  评论(0编辑  收藏  举报