编程之美2.11寻找最近点对Java版一

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 *
 * 2.11寻找最近的点对
 */
public class SearchLengthMinPoints {

    public static void main(String[] args) {
        int[] arry = new int[]{8,3,12,18,26};
        //解法一   一维 把每两个点之间的距离都求出来;二维情况一样,求两点间距离|x1-x2|^2+|y1-y2|^2再开根号
        int[] num1 = searchLength1(arry);
        System.out.println("距离最近的两个点:" + num1[0] + "、" + num1[1]);

        //解法二  先排序,然后求两点间距离;无法扩展到二维
        int[] num2 = searchLength2(arry);
        System.out.println("距离最近的两个点:" + num2[0] + "、" + num2[1]);

        //解法三  一维 分治思想
        List<Integer> list = new ArrayList();
        for (int i = 0; i < arry.length; i++) {
            list.add(arry[i]);
        }
        List<Integer> num3 = searchLength3(list);
        System.out.println("距离最近的两个点:" + num3.get(0) + "、" + num3.get(1) + "距离为:" + num3.get(2));
    }

    private static int[] searchLength1(int[] arry) {
        int[] result = new int[2];
        int sub = Math.abs(arry[0] - arry[1]);
        for (int i = 0; i < arry.length; i++) {
            for (int j = i + 1; j < arry.length; j++) {
                int tmp = Math.abs(arry[i] - arry[j]);
                if (sub > tmp) {
                    sub = tmp;
                    result[0] = arry[i];
                    result[1] = arry[j];
                }
            }
        }
        return result;
    }

    private static int[] searchLength2(int[] arry) {
        int[] result = new int[2];
        quick_sort(arry, 0, arry.length - 1);
        int sub = Math.abs(arry[0] - arry[1]);
        for (int i = 2; i < arry.length; i++) {

            int tmp = Math.abs(arry[i - 1] - arry[i]);
            if (sub > tmp) {
                sub = tmp;
                result[0] = arry[i - 1];
                result[1] = arry[i];
            }

        }
        return result;
    }

    static void quick_sort(int s[], int l, int r) {
        if (l < r) {
            //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
            int i = l, j = r, x = s[l];
            while (i < j) {
                while (i < j && s[j] >= x) // 从右向左找第一个小于x的数
                {
                    j--;
                }
                if (i < j) {
                    s[i++] = s[j];
                }

                while (i < j && s[i] < x) // 从左向右找第一个大于等于x的数
                {
                    i++;
                }
                if (i < j) {
                    s[j--] = s[i];
                }
            }
            s[i] = x;
            quick_sort(s, l, i - 1); // 递归调用 
            quick_sort(s, i + 1, r);
        }
    }

    private static List<Integer> searchLength3(List<Integer> list) {
        List result = new ArrayList();
        if (list.size() <= 2) {
            if (list.size() == 2) {
                result.add(list.get(1));
                result.add(list.get(0));
                result.add(Math.abs(list.get(0) - list.get(1)));

            } else {
                result.add(list.get(0));
                result.add(list.get(0));
                result.add(0);
            }
           
            return result;

        }
        int mid = list.size() / 2;
        int k = list.get(mid);
        List<Integer> list_left = new ArrayList<Integer>();
        List<Integer> list_right = new ArrayList();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) < k) {
                list_left.add(list.get(i));
            } else if (list.get(i) > k) {
                list_right.add(list.get(i));
            }
        }

        if (list_left.size() > list_right.size()) {
            list_right.add(k);
        } else {
            list_left.add(k);
        }
     
        List<Integer> result_left = searchLength3(list_left);
        List<Integer> result_right = searchLength3(list_right);
        //左边的最大值和右边的最小值的差
         Collections.sort(list_left);
         Collections.sort(list_right);
        int sub = Math.abs( list_left.get(list_left.size()-1)- list_right.get(0));
        int sub_left = result_left.get(2);
        int sub_right = result_right.get(2);
        if (sub_left > 0 && result_left.get(2) < sub) {
            if (sub_right > 0 && sub_right < sub_left) {
                result.addAll(result_right);
            } else {
                result.addAll(result_left);
            }
        } else {
            if (sub_right > 0 && sub_right < sub) {
                result.addAll(result_right);
            } else {
                result.add(list_left.get(list_left.size()-1));
                result.add(list_right.get(0));
                result.add(sub);
            }
        }
       
        return result;
    }
}

没觉得一维的分治算法有多简化啊。。。还是我的代码太复杂了

    原文作者:哒宝甜
    原文地址: https://blog.csdn.net/tt285955925/article/details/51730899
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞