分而治之算法
Divide and Conquer is an algorithmic paradigm (sometimes mistakenly called "Divide and Concur" - a funny and apt name), similar to Greedy and Dynamic Programming. A typical Divide and Conquer algorithm solves a problem using the following three steps.
“分而治之”是一种算法范式(有时被错误地称为“ Divide and Concur”(一个有趣且恰当的名称)),类似于“贪婪和动态编程”。 典型的分而治之算法使用以下三个步骤来解决问题。
Divide: Break the given problem into subproblems of same type. This step involves breaking the problem into smaller sub-problems. Sub-problems should represent a part of the original problem. This step generally takes a recursive approach to divide the problem until no sub-problem is further divisible. At this stage, sub-problems become atomic in nature but still represent some part of the actual problem.
划分 :将给定问题分解为相同类型的子问题。 此步骤涉及将问题分解为较小的子问题。 子问题应该代表原始问题的一部分。 此步骤通常采用递归方法来划分问题,直到没有子问题可以进一步分割为止。 在这个阶段,子问题本质上已成为原子问题,但仍代表实际问题的一部分。
Conquer: Recursively solve these sub-problems. This step receives a lot of smaller sub-problems to be solved. Generally, at this level, the problems are considered 'solved' on their own.
征服 :递归解决这些子问题。 此步骤收到许多要解决的较小子问题。 通常,在此级别上,问题被认为是“已解决”。
Combine: Appropriately combine the answers. When the smaller sub-problems are solved, this stage recursively combines them until they formulate a solution of the original problem. This algorithmic approach works recursively and conquer & merge steps works so close that they appear as one.
合并 :适当合并答案。 解决了较小的子问题后,此阶段将它们递归组合,直到它们为原始问题制定了解决方案。 这种算法方法递归地起作用,征服和合并步骤如此接近以至于它们看起来像一个。
This method usually allows us to reduce the time complexity by a large extent.
这种方法通常可以使我们在很大程度上减少时间复杂度。
For example, Bubble Sort uses a complexity of O(n^2)
, whereas quicksort (an application Of Divide And Conquer) reduces the time complexity to O(nlog(n))
. Linear Search has time complexity O(n)
, whereas Binary Search (an application Of Divide And Conquer) reduces time complexity to O(log(n))
.
例如,冒泡排序使用O(n^2)
的复杂度,而快速排序(分而治之的应用程序)将时间复杂度降低为O(nlog(n))
。 线性搜索的时间复杂度为O(n)
,而二进制搜索(分而治之的应用)将时间复杂度降低为O(log(n))
。
Following are some standard algorithms that are of the Divide and Conquer algorithms variety.
以下是分而治之算法的一些标准算法。
Binary Search is a searching algorithm. In each step, the algorithm compares the input element (x) with the value of the middle element in array. If the values match, return the index of middle. Otherwise, if x is less than the middle element, then the algorithm recurs to the left side of the middle element, else it recurs to the right side of the middle element.
二进制搜索是一种搜索算法。 在每个步骤中,算法都会将输入元素(x)与数组中中间元素的值进行比较。 如果值匹配,则返回中间索引。 否则,如果x小于中间元素,则算法递归到中间元素的左侧,否则算法递归到中间元素的右侧。
Quicksort is a sorting algorithm. The algorithm picks a pivot element, rearranges the array elements in such a way that all elements smaller than the picked pivot element move to the left side of the pivot, and all greater elements move to the right side. Finally, the algorithm recursively sorts the subarrays on left and right of pivot element.
Quicksort是一种排序算法。 该算法选择一个枢轴元素,以这样一种方式重新排列数组元素:所有小于所拾取枢轴元素的元素都移到枢轴的左侧,所有更大的元素都移到右侧。 最后,该算法对枢轴元素左右两侧的子数组进行递归排序。
Merge Sort is also a sorting algorithm. The algorithm divides the array into two halves, recursively sorts them, and finally merges the two sorted halves. The time complexity of this algorithm is O(nLogn)
, be it best case, average case or worst case. It's time complexity can be easily understood from the recurrence equates to: T(n) = 2T(n/2) + n
.
合并排序也是一种排序算法。 该算法将数组分为两个半部分,对它们进行递归排序,最后合并两个排序的半部分。 该算法的时间复杂度为O(nLogn)
,无论是最佳情况,平均情况还是最坏情况。 从时间等于T(n) = 2T(n/2) + n
可以很容易地理解它的时间复杂度。
Closest Pair of Points The problem is to find the closest pair of points in a set of points in x-y plane. The problem can be solved in O(n^2)
time by calculating distances of every pair of points and comparing the distances to find the minimum. The Divide and Conquer algorithm solves the problem in O(nLogn)
time.
最接近的点对问题是在xy平面中的一组点中找到最接近的点对。 通过计算每对点的距离并比较距离以找出最小值,可以在O(n^2)
时间内解决该问题。 分而治之算法解决了O(nLogn)
时间的问题。
Strassen’s Algorithm is an efficient algorithm to multiply two matrices. A simple method to multiply two matrices need 3 nested loops and is O(n^3)
. Strassen’s algorithm multiplies two matrices in O(n^2.8974)
time.
Strassen算法是将两个矩阵相乘的高效算法。 一个简单的将两个矩阵相乘的方法需要3个嵌套循环,并且为O(n^3)
。 Strassen算法在O(n^2.8974)
时间内将两个矩阵相乘。
Cooley–Tukey Fast Fourier Transform (FFT) algorithm is the most common algorithm for FFT. It is a divide and conquer algorithm which works in O(nlogn)
time.
Cooley–Tukey快速傅立叶变换(FFT)算法是FFT最常用的算法。 这是一种分治法,可在O(nlogn)
时间内使用。
The Karatsuba algorithm was the first multiplication algorithm asymptotically faster than the quadratic "grade school" algorithm. It reduces the multiplication of two n-digit numbers to at most to n^1.585 (which is approximation of log of 3 in base 2) single digit products. It is therefore faster than the classical algorithm, which requires n^2 single-digit products.
Karatsuba算法是第一个渐进地快于二次“等级学校”算法的乘法算法。 它将两个n位数字的乘积最多减少到n ^ 1.585(以2为底的对数3的对数)。 因此,它比经典算法快,后者需要n ^ 2个单位的乘积。
Both paradigms (D & C and DP) divide the given problem into subproblems and solve subproblems. How to choose one of them for a given problem? Divide and Conquer should be used when same subproblems are not evaluated many times. Otherwise Dynamic Programming or Memoization should be used.
两种范例(D&C和DP)都将给定的问题分为子问题并解决子问题。 如何为给定问题选择其中之一? 当相同子问题没有被多次评估时,应使用分而治之。 否则,应使用动态编程或记忆。
For example, Binary Search is a Divide and Conquer algorithm, we never evaluate the same subproblems again. On the other hand, for calculating the nth Fibonacci number, Dynamic Programming should be preferred.
例如,二进制搜索是一种分而治之的算法,我们再也不会评估相同的子问题。 另一方面,为了计算第n个斐波那契数,应首选动态编程。
翻译自: https://www.freecodecamp.org/news/divide-and-conquer-algorithms/
分而治之算法