五大常用算法--分治

Posted harry1989

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五大常用算法--分治相关的知识,希望对你有一定的参考价值。

概念

Divide and Conquer is an algorithmic paradigm. A typical Divide and Conquer algorithm solves a problem using following three steps.
Divide: Break the given problem into subproblems of same type.
Conquer: Recursively solve these subproblems
Combine: Appropriately combine the answer.

常见应用

快排

/* low  --> Starting index,  high  --> Ending index */
quickSort(arr[], low, high)
{
    if (low < high)
    {
        /* pi is partitioning index, arr[pi] is now
           at right place */
        pi = partition(arr, low, high);

        quickSort(arr, low, pi - 1);  // Before pi
        quickSort(arr, pi + 1, high); // After pi
    }
}
/* This function takes last element as pivot, places
   the pivot element at its correct position in sorted
    array, and places all smaller (smaller than pivot)
   to left of pivot and all greater elements to right
   of pivot */
partition (arr[], low, high)
{
    // pivot (Element to be placed at right position)
    pivot = arr[high];  
 
    i = (low - 1)  // Index of smaller element

    for (j = low; j <= high- 1; j++)
    {
        // If current element is smaller than the pivot
        if (arr[j] < pivot)
        {
            i++;    // increment index of smaller element
            swap arr[i] and arr[j]
        }
    }
    swap arr[i + 1] and arr[high])
    return (i + 1)
}

归并排序

最大子序和 leetcode 53

// 输入: [-2,1,-3,4,-1,2,1,-5,4],
// 输出: 6
// 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
// 该代码用分治法比较难以理解,不过却是一道好题。 也可以通过DP、贪心算法求解
class Solution { public int crossSum(int[] nums, int left, int right, int p) { if (left == right) return nums[left]; int leftSubsum = Integer.MIN_VALUE; int currSum = 0; for(int i = p; i > left - 1; --i) { currSum += nums[i]; leftSubsum = Math.max(leftSubsum, currSum); } int rightSubsum = Integer.MIN_VALUE; currSum = 0; for(int i = p + 1; i < right + 1; ++i) { currSum += nums[i]; rightSubsum = Math.max(rightSubsum, currSum); } return leftSubsum + rightSubsum; } public int helper(int[] nums, int left, int right) { if (left == right) return nums[left]; int p = (left + right) / 2; int leftSum = helper(nums, left, p); int rightSum = helper(nums, p + 1, right); int crossSum = crossSum(nums, left, right, p); return Math.max(Math.max(leftSum, rightSum), crossSum); } public int maxSubArray(int[] nums) { return helper(nums, 0, nums.length - 1); } }

 

参考资料

1. https://www.geeksforgeeks.org/divide-and-conquer/#standard

2. https://www.geeksforgeeks.org/quick-sort/

3. https://leetcode-cn.com/problems/maximum-subarray/solution/zui-da-zi-xu-he-by-leetcode/

 

/* low  --> Starting index,  high  --> Ending index */
quickSort(arr[], low, high)
{
    if (low < high)
    {
        /* pi is partitioning index, arr[pi] is now
           at right place */
        pi = partition(arr, low, high);

        quickSort(arr, low, pi - 1);  // Before pi
        quickSort(arr, pi + 1, high); // After pi
    }
}

以上是关于五大常用算法--分治的主要内容,如果未能解决你的问题,请参考以下文章

五大常用算法一文搞懂分治算法

五大常用算法--分治

五大常用算法:分治动态规划贪心回溯和分支界定

五大常用算法:分治动态规划贪心回溯和分支界定

五大常用算法:分治动态规划贪心回溯和分支界定

[转]五大常用算法:分治动态规划贪心回溯和分支界定