📜  分而治之的算法|介绍

📅  最后修改于: 2021-09-16 11:00:02             🧑  作者: Mango

在本文中,我们将讨论分而治之技术如何有用,以及我们如何使用 DAC 技术方法解决问题。在本节中,我们将讨论以下主题。

1. Introduction to DAC.
2. Algorithms under DAC techniques.
3. Recurrence Relation for DAC algorithm.
4. Problems using DAC technique.

分而治之
该技术可以分为以下三个部分:

  1. 划分:这涉及将问题划分为更小的子问题。
  2. 征服:通过递归调用直到解决来解决子问题。
  3. 合并:合并子问题,得到整个问题的最终解。

下面是一些遵循分而治之算法的标准算法。

  1. 快速排序是一种排序算法。该算法选择一个枢轴元素并重新排列数组元素,以便所有小于所选枢轴元素的元素移动到枢轴的左侧,所有较大的元素移动到右侧。最后,该算法递归地对枢轴元素左侧和右侧的子数组进行排序。
  2. 归并排序也是一种排序算法。该算法将数组分成两半,递归排序,最后合并已排序的两半。
  3. 最近的一对点问题是在 xy 平面的一组点中找到最近的一对点。通过计算每对点的距离并比较距离以找到最小值,可以在 O(n^2) 时间内解决该问题。分而治之算法在 O(N log N) 时间内解决了这个问题。
  4. Strassen 算法是一种将两个矩阵相乘的有效算法。将两个矩阵相乘的简单方法需要 3 个嵌套循环,并且是 O(n^3)。 Strassen 算法在 O(n^2.8974) 时间内将两个矩阵相乘。
  5. Cooley-Tukey 快速傅立叶变换 (FFT) 算法是最常用的 FFT 算法。它是一种分治算法,在 O(N log N) 时间内工作。
  6. 快速乘法的Karatsuba算法最多将两个n位数字相乘

3n^{log_{2}^{3}}\approx 3n^{1.585}

一般的个位数乘法(准确地说是n^{\log_23}  n是 2 的幂时)。因此,它比需要n 2个个位数乘积的经典算法更快。特别地,如果n = 2 10 = 1024,则准确计数分别为 3 10 = 59, 049 和 (2 10 ) 2 = 1, 048, 576。

什么不符合分而治之的条件:

二分搜索是一种搜索算法。在每一步中,算法都会将输入元素 x 与数组中中间元素的值进行比较。如果值匹配,则返回中间的索引。否则,如果 x 小于中间元素,则算法针对中间元素的左侧递归,否则针对中间元素的右侧递归。与流行的看法相反,这不是一个分而治之的例子,因为每一步只有一个子问题(分而治之要求必须有两个或更多的子问题),因此这是一个减少和征服。

分而治之算法:

DAC(a, i, j)
{
    if(small(a, i, j))
      return(Solution(a, i, j))
    else 
      m = divide(a, i, j)               // f1(n)
      b = DAC(a, i, mid)                 // T(n/2)
      c = DAC(a, mid+1, j)            // T(n/2)
      d = combine(b, c)                 // f2(n)
   return(d)
}

DAC算法的递归关系:
这是上述程序的递推关系。

O(1) if n is small
T(n) =     f1(n) + 2T(n/2) + f2(n)

例子:
查找给定数组中的最大和最小元素。

Input: { 70, 250, 50, 80, 140, 12, 14 }
Output: The minimum number in a given array is : 12
The maximum number in a given array is : 250

方法:从给定数组中找到最大和最小元素是分治法的应用。在这个问题中,我们将找到给定数组中的最大和最小元素。在这个问题中,我们使用分治法(DAC),它具有分、治和组合三个步骤。

对于最大值:
在这个问题中,我们使用递归方法找到最大值,我们将看到只剩下两个元素,然后我们可以轻松地使用条件,即 if(a[index]>a[index+1].)
在程序行中,a[index] 和 a[index+1])condition 将确保左侧只有两个元素。

在上述条件中,我们检查了左侧条件以找出最大值。现在,我们将看到找到最大值的右侧条件。
检查数组当前索引右侧的递归函数。

现在,我们将比较条件并检查给定数组当前索引处的右侧。
在给定的程序中,我们将实现此逻辑以检查当前索引右侧的条件。

最低:
在这个问题中,我们将实施递归方法来找到最小值。在给定的数组中。

现在,我们将检查给定数组右侧的条件。

现在,我们将检查条件以找到右侧的最小值。

执行:

C++
// C++ code to demonstrate Divide and
// Conquer Algorithm#include
# include
using namespace std;
 
// function to find the maximum no.
// in a given array.
int DAC_Max(int arr[], int index, int l)
{
    int max;
    if(index >= l - 2)
    {
        if(arr[index] > arr[index + 1])
          return arr[index];
        else
          return arr[index + 1];
    } 
    max = DAC_Max(arr, index + 1, l);   
    if(arr[index] > max)
       return arr[index];
    else
       return max;
}
 
// Function to find the minimum no.
// in a given array
int DAC_Min(int arr[], int index, int l)
{
    int min;
    if(index >= l - 2)
    {
        if(arr[index] < arr[index + 1])
          return arr[index];
        else
          return arr[index + 1];
    }
     
    min = DAC_Min(arr, index + 1, l);  
    if(arr[index] < min)
       return arr[index];
    else
       return min;
}
 
// Driver code
int main()
{
    int arr[] = {120, 34, 54, 32, 58, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);
    int max, min;
    max = DAC_Max(arr, 0, n);
    min = DAC_Min(arr, 0, n);
    cout << "Maximum: " << max << endl;
    cout << "Minimum: " << min << endl;
    return 0;
}
 
// This code is contributed by probinsah.


C
// C code to demonstrate Divide and
// Conquer Algorithm
#include 
int DAC_Max(int a[], int index, int l);
int DAC_Min(int a[], int index, int l);
 
// function to find the maximum no.
// in a given array.
int DAC_Max(int a[], int index, int l)
{
    int max;
    if (index >= l - 2) {
        if (a[index] > a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // logic to find the Maximum element
    // in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max)
        return a[index];
    else
        return max;
}
 
// Function to find the minimum no.
// in a given array.
int DAC_Min(int a[], int index, int l)
{
    int min;
    if (index >= l - 2) {
        if (a[index] < a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Minimum element
    // in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min)
        return a[index];
    else
        return min;
}
 
// Driver Code
int main()
{
    // Defining the variables
    int min, max, N;
 
    // Initializing the array
    int a[7] = { 70, 250, 50, 80, 140, 12, 14 };
 
    // recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    // recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
    printf("The minimum number in a given array is : %d\n", min);
    printf("The maximum number in a given array is : %d", max);
    return 0;
}
 
// This code is contributed by Ashish Rana (GFG Team)


Java
// Java code to demonstrate Divide and
// Conquer Algorithm
class GFG{
 
// Function to find the maximum no.
// in a given array.
static int DAC_Max(int a[], int index, int l)
{
    int max;
     
    if (index >= l - 2)
    {
        if (a[index] > a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Maximum element
    // in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max)
        return a[index];
    else
        return max;
}
 
// Function to find the minimum no.
// in a given array.
static int DAC_Min(int a[], int index, int l)
{
    int min;
    if (index >= l - 2)
    {
        if (a[index] < a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Minimum element
    // in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min)
        return a[index];
    else
        return min;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Defining the variables
    int min, max;
 
    // Initializing the array
    int a[] = { 70, 250, 50, 80, 140, 12, 14 };
 
    // Recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    // Recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
     
    System.out.printf("The minimum number in " +
                      "a given array is : %d\n", min);
    System.out.printf("The maximum number in " +
                      "a given array is : %d", max);
}
}
 
// This code is contributed by Princi Singh


C#
// C# code to demonstrate Divide and
// Conquer Algorithm
using System;
class GFG
{
 
// Function to find the maximum no.
// in a given array.
static int DAC_Max(int []a, int index, int l)
{
    int max;
     
    if (index >= l - 2)
    {
        if (a[index] > a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Maximum element
    // in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max)
        return a[index];
    else
        return max;
}
 
// Function to find the minimum no.
// in a given array.
static int DAC_Min(int []a, int index, int l)
{
    int min;
    if (index >= l - 2)
    {
        if (a[index] < a[index + 1])
            return a[index];
        else
            return a[index + 1];
    }
 
    // Logic to find the Minimum element
    // in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min)
        return a[index];
    else
        return min;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Defining the variables
    int min, max;
 
    // Initializing the array
    int []a = {70, 250, 50, 80, 140, 12, 14};
 
    // Recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    // Recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
     
    Console.Write("The minimum number in " +
                      "a given array is : {0}\n", min);
    Console.Write("The maximum number in " +
                      "a given array is : {0}", max);
}
}
 
// This code contributed by shikhasingrajput


Python3
# Python3 code to demonstrate Divide and
# Conquer Algorithm
 
# Function to find the maximum no.
# in a given array.
def DAC_Max(a, index, l):
    max = -1;
 
    if (index >= l - 2):
        if (a[index] > a[index + 1]):
            return a[index];
        else:
            return a[index + 1];
 
    # Logic to find the Maximum element
    # in the given array.
    max = DAC_Max(a, index + 1, l);
 
    if (a[index] > max):
        return a[index];
    else:
        return max;
 
# Function to find the minimum no.
# in a given array.
def DAC_Min(a, index, l):
    min = 0;
    if (index >= l - 2):
        if (a[index] < a[index + 1]):
            return a[index];
        else:
            return a[index + 1];
 
    # Logic to find the Minimum element
    # in the given array.
    min = DAC_Min(a, index + 1, l);
 
    if (a[index] < min):
        return a[index];
    else:
        return min;
 
# Driver Code
if __name__ == '__main__':
   
    # Defining the variables
    min, max = 0, -1;
 
    # Initializing the array
    a = [70, 250, 50, 80, 140, 12, 14];
 
    # Recursion - DAC_Max function called
    max = DAC_Max(a, 0, 7);
 
    # Recursion - DAC_Max function called
    min = DAC_Min(a, 0, 7);
    print("The minimum number in a given array is : ", min);
    print("The maximum number in a given array is : ", max);
 
# This code is contributed by 29AjayKumar


Javascript


输出
Maximum: 120
Minimum: 11

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程