算法篇——数对和问题

102 阅读1分钟

内容六

image-20201015110233117

思路:像这种一对一对的东西首先想到了合并排序,因为合并排序合并的过程就遍历了所有的数对。现在只要判断是否存在一个和为S的数对就行。

分成子问题后,有序了,可以用二分搜索查找。

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author SJ
 * @date 2020/10/15
 */
public class HasSum {
    public HasSum(int length) {
        temp=new Integer[length];
    }

    public static Integer[] temp ;
    public static boolean merge(int[] nums, int left, int right, int sum) {

        for (int i = left; i <= right; i++) {
            temp[i] = nums[i];
        }
        int middle = (left + right) / 2;
        int l = left;
        int r = middle + 1;

        for (int i = left; i <= right; i++) {
            //左边合并完成,右边还有剩余
            if (l == middle + 1 && r < right + 1)
                nums[i] = temp[r++];
                //右边合并完成,左边还有剩余
            else if (r == right + 1 && l < middle + 1)
                nums[i] = temp[l++];
            else if (temp[l] <= temp[r]) {
                nums[i] = temp[l++];
                //用二分搜索
                int index = Arrays.binarySearch(temp, r, right, sum - nums[i]);
                if (index >= 0) {
                   // System.out.println(nums[i] + "," + temp[index]);
                    return true;
                }

            } else {
                nums[i] = temp[r++];
                int index = Arrays.binarySearch(temp, l, middle, sum - nums[i]);
                if (index >= 0) {
                   // System.out.println(nums[i] + "," + temp[index]);
                    return true;
                }


            }

        }
        return false;

    }

    public static boolean mergeSort(int[] nums, int left, int right, int sum) {
        boolean leftCount = false;
        boolean rightCount = false;
        boolean mix = false;
        if (left == right)
            return false;
        else if (left < right) {
            leftCount = mergeSort(nums, left, (left + right) / 2, sum);
            rightCount = mergeSort(nums, (left + right) / 2 + 1, right, sum);
            mix = merge(nums, left, right, sum);

        }
        return leftCount || rightCount || mix;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int length = scanner.nextInt();
        new HasSum(length);
        int[] nums = new int[length];
//        int[] nums={3,5,7,2,1};
        int sum = scanner.nextInt();
        for (int i = 0; i < length; i++) {
            nums[i] = scanner.nextInt();
        }
        boolean b = mergeSort(nums, 0, nums.length - 1, sum);
        if (b)
            System.out.println("YES");
        else
            System.out.println("NO");


    }

}

结果:

"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe"...
5 7
3 6 7 2 1
YES

Process finished with exit code 0

时间复杂度O(nlgn)O(nlgn) 空间O(n)