美文网首页
2019-08-22 分治算法

2019-08-22 分治算法

作者: Phoebe_Liu | 来源:发表于2019-08-22 14:08 被阅读0次
  1. Reverse Pairs——分治算法
    Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2nums[j].
    You need to return the number of important reverse pairs in the given array.
    Example1:
    Input: [1,3,2,3,1]
    Output: 2
    Example2:
    Input: [2,4,3,5,1]
    Output: 3
    分析:采用类似于归并算法的思想:不断的将数组对半拆分成子数组,拆到最小的数组后开始排序,然后一层一层的返回,最后原数组也是有序的了。
    In each round, we divide our array into two parts and sort them. So after "int cnt = mergeSort(nums, s, mid) + mergeSort(nums, mid+1, e); ", the left part and the right part are sorted and now our only job is to count how many pairs of number (leftPart[i], rightPart[j]) satisfies leftPart[i] <= 2
    rightPart[j].
    For example,
    left: 4 6 8 right: 1 2 3
    so we use two pointers to travel left and right parts. For each leftPart[i], if j<=e && nums[i]/2.0 > nums[j], we just continue to move j to the end, to increase rightPart[j], until it is valid. Like in our example, left's 4 can match 1 and 2; left's 6 can match 1, 2, 3, and left's 8 can match 1, 2, 3. So in this particular round, there are 8 pairs found, so we increases our total by 8.
 public int reversePairs(int[] nums) {
        return  mergeSort(nums, 0 , nums.length-1);
    }
    
    public int mergeSort(int[] nums, int s, int e){
        if(s>=e)
            return 0;
        int mid = s + (e-s)/2;
        int result = mergeSort(nums, s, mid) + mergeSort(nums, mid+1, e);
        for(int i=s, j=mid+1; i<=mid; i++){
            while(j<=e && nums[i]>2.0*nums[j])
                j++;
            result += j-(mid+1);
        }
        Arrays.sort(nums,s, e+1);
        return result;
    }
  1. Kth Largest Element in an Array
    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
    Example 1:
    Input: [3,2,1,5,6,4] and k = 2
    Output: 5
    分析:借用快排的思想,解决这个问题
class Solution {
    public int findKthLargest(int[] nums, int k) {
        return findKthLargest(nums,0, nums.length-1, nums.length-k);
    }
    
    public int findKthLargest(int[] nums, int start, int end, int k){
        if(start>end)
            return Integer.MAX_VALUE; 
        
        int pivot = nums[end];
        int newIndex = start;
        for(int i =start; i <end; i++){
            if(nums[i]<=pivot){  // Put numbers < pivot to pivot's left
                swap(nums, newIndex, i);
                newIndex++;
            }
        }
        swap(nums, newIndex, end);
        if(newIndex == k)// Found kth smallest number
            return nums[newIndex];
        else if(newIndex < k)// Check right part
            return findKthLargest(nums, newIndex+1, end, k);
        else { // Check left part
            return findKthLargest(nums, 0, newIndex-1, k);
        }
    }
    
    public void swap(int[] nums, int i ,int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}
  1. K Closest Points to Origin
    We have a list of points on the plane. Find the K closest points to the origin (0, 0).
    (Here, the distance between two points on a plane is the Euclidean distance.)
    You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in.)
    Example 1:
    Input: points = [[1,3],[-2,2]], K = 1
    Output: [[-2,2]]
    Explanation:
    The distance between (1, 3) and the origin is sqrt(10).
    The distance between (-2, 2) and the origin is sqrt(8).
    Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.
    We only want the closest K = 1 points from the origin, so the answer is just [[-2,2]].
    分析:利用快排思想
class Solution {
    public static int[][] kClosest(int[][] points, int K) {
        int len = points.length;
        return findKClosest(points, 0, len-1, K);
    }

    public static int[][] findKClosest(int[][] points, int start, int end, int K){
        if(start > end)
            return null;

        // quict sort
        int i=start, j=end;
        int[] pivot = points[i];
        while(i < j){
            while(i<j && compare(points[j],pivot)>=0 )
                j--;
            points[i] = points[j];
            while(i<j && compare(points[i],pivot)<=0)
                i++;
            points[j] = points[i];
        }
        points[i] = pivot;

        // judge
        if(i==K-1){
            return Arrays.copyOfRange(points, 0, K);
        }
        else if(i<K-1){
            return findKClosest(points, i+1, end, K);
        }
        else
            return findKClosest(points, start, i-1, K);
    }

    private static int compare(int[] p1, int[] p2) {
        return p1[0] * p1[0] + p1[1] * p1[1] - p2[0] * p2[0] - p2[1] * p2[1];
    }
}

相关文章

  • 分治算法

    文章结构 如何理解分治算法 分治算法应用举例 1. 如何理解分治算法 1.1 分治算法的核心思想 分治算法的核心思...

  • 2019-08-22 分治算法

    Reverse Pairs——分治算法Given an array nums, we call (i, j) an...

  • 算法导论第2.3章 - 分治算法

    分治算法 递归:算法一次或多次递归地调用其自身已解决紧密相关的若干子问题。这些算法遵循分治法的思想。 分治算法三个...

  • 从分治算法到 MapReduce

    从分治算法说起 要说 MapReduce 就不得不说分治算法,而分治算法其实说白了,就是四个字 分而治之 。其实就...

  • Leetcode-Java(二十五)

    241. Different Ways to Add Parentheses 采用分治算法,分治算法的基本思想是将...

  • 09《算法入门教程》分治算法

    1. 前言 本节内容是分治算法系列之一:分治算法的介绍,主要介绍了分治算法的定义及基本思想和实现策略,然后我们介绍...

  • 分治算法

    理解分治算法 分而治之

  • 分治算法

    分治是一种思想体现,就是把一个大的问题分为若干个子问题,这些子问题相互独立且与原问题性质相同然后在子问题继续向下分...

  • 分治算法

    分治算法字面意思就是将一个复杂的数据进行分开计算,分治 的策略就是: 一个分治法将规模为n的问题分成k个规模为n/...

  • 分治算法

    http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741...

网友评论

      本文标题:2019-08-22 分治算法

      本文链接:https://www.haomeiwen.com/subject/khagsctx.html