分而治之算法找到两个有序元素之间的最大差异

Posted

技术标签:

【中文标题】分而治之算法找到两个有序元素之间的最大差异【英文标题】:Divide and Conquer Algo to find maximum difference between two ordered elements 【发布时间】:2014-07-26 04:13:29 【问题描述】:

给定一个整数数组 arr[],找出任意两个元素之间的差,使得较大的元素出现在 arr[] 中较小的数字之后。

Max Difference = Max  arr[x] - arr[y] | x > y 

例子:

如果数组是[2, 3, 10, 6, 4, 8, 1, 7],那么返回值应该是8(10和2之间的差异)。

如果数组是[ 7, 9, 5, 6, 3, 2 ],那么返回值应该是2(7和9之间的差异)

我的算法:

我想到了使用 D&C 算法。 说明

2, 3, 10, 6, 4, 8, 1, 7

then

2,3,10,6      and     4,8,1,7

then

2,3  and 10,6  and  4,8 and 1,7

then

2 and 3   10 and 6   4 and 8    1 and 7

由于这些元素将保持相同的顺序,我将得到最大的差异,这里是 6。

现在我将返回合并这些数组,并再次找到第一个块的最小值和第二个块的最大值之间的差异,并继续这样做直到结束。

我无法在我的代码中实现这一点。 任何人都可以为此提供一个伪代码吗?

【问题讨论】:

您能否把您的问题说得更清楚些。似乎您正在尝试先实现合并排序,然后再实现其他目标。 @shekharsuman 我想要最大的 (arr[x]-arr[y]) 使得索引 x > y。 【参考方案1】:

我们有max A[i] - A[j] | i > j = max A[i] - min A[j] | j < i | i ,产生 一个简单的 O(n) 算法:

prefix_min = A[0]
result = -infinity
for i := 1 to n - 1:
    # invariant: We have prefix_min = min  A[j] | j < i 
    result = max(result, A[i] - prefix_min)
    prefix_min = min(prefix_min, A[i])

分治法在概念上更复杂,但也导致线性时间解决方案(具有更高的常数因子)。

【讨论】:

非常优雅的解决方案。 问的问题是分而治之的算法,你已经实现了 kadane 的算法【参考方案2】:

假设你要找到最大的Difference LD(A[])

根据需要完成伪代码:

将数组分成两部分 A1[] 和 A2[]。

Find minimum & maximum element in A1[] and LD(A1).
Find minimum & maximum element in A2[] and LD(A2).

LD(A) = max( LD(A1), LD(A2), MAX(A2) - MIN(A1) )
MAX(A) = max( MAX(A1), MAX(A2) )
MIN(A) = min( MIN(A1), MIN(A2) )

基本情况 (length(A) == 2):

If A[1] > A[0], 
  LD(A) = A[1] - A[0].
  MAX(A) = A[1]
  MIN(A) = A[0]
else
  LD(A) = 0.
  MAX(A) = A[0]
  MIN(A) = A[1]

注意:

If (length(A) == 1)
    LD(A) = 0
    MIN(A) = MAX(A) = A[0]

同样,您可以计算每个子数组中的最小和最大元素。

【讨论】:

-你认为他问的是同一个问题吗?其实这就是他要实现的算法!您的回答不符合他的问题的输出!请再看一遍他的例子。 @shekharsuman 他想要算法的伪代码。我已经提供给他了。 @AbhishekBansal 你能给出一个线性时间解决方案吗?现在写它的运行时间是O(nlogn)。【参考方案3】:

以下是 C 语言中使用分而治之的代码。 请。请随时发表评论。

#include <stdio.h>

struct data
    int min_;
    int max_;
;

struct data crossminmax(int *p,int lo,int mid,int hi)
    int i,min,max;
    struct data temp;

    min = p[mid];
    for(i=mid;i>=lo;i--)
        if(p[i] < min)
            min = p[i];
        
    

    max = p[mid+1];
    for(i=mid+1;i<=hi;i++)
        if(p[i] > max)
            max = p[i];
        
    
    temp.min_ = min;
    temp.max_ = max;
    return temp;


/* MinMax calculates the difference between Biggest and Smallest element  *
 * of an array using divide and conquer principles such that the position * 
 * of Biggest element is always greater than the Samllest element         */

struct data minmax(int *p,int lo,int hi)
    int mid,leftdiff,rightdiff,crossdiff;
    struct data left,right,cross,temp;

    if(lo == hi)
        temp.min_ = p[lo];
        temp.max_ = p[hi];
        return temp;
    

    mid = (lo+hi)/2;
    left = minmax(p,lo,mid);
    right = minmax(p,mid+1,hi);

    cross = crossminmax(p,lo,mid,hi);
    leftdiff = left.max_ - left.min_;
    rightdiff = right.max_ - right.min_;
    crossdiff = cross.max_ - cross.min_;

    if(leftdiff > rightdiff && leftdiff > crossdiff)
        return left;
    else if(rightdiff > crossdiff)
        return right;
    else
        return cross;
    


int main()
    int arr[] = 5,2,3,10,1,3,16,4,3;
    struct data dt;
    dt = minmax(arr,0,8);
    printf("Max difference = %d, Max Element=%d, Min Element = %d  \n",dt.max_ - dt.min_,dt.max_,dt.min_);
    return 0;

【讨论】:

欢迎来到 Stack Overflow!虽然这可能会回答问题,但it would be preferable 将在此处包含答案的基本部分,并提供链接以供参考。 感谢 Nathan 和 chiwangc 的建议【参考方案4】:

数组中的最大差异

condition : - larger number should appear after smaller number
 10, 3, 6, 4, 8, 1, 7      6
 2, 3, 10, 6, 4, 8, 1      8
 7, 9, 5, 6, 3, 2          1
 1, 2, 3, 4                3
 4, 3, 2, 1                0



#include<stdio.h>
int main()
  int n = 7;
  int arr[7] =  10, 3, 6, 14, 8, 1, 7 ;

  int i;
  int max_diff = 0;
  int min = arr[0];

  for( i=0; i<n; i++)
    if( (arr[i] - min) > max_diff )
      max_diff = arr[i] - min;
    

    if(arr[i] < min)
      min = arr[i];
    
  
  printf("max diff = %d", max_diff);

  return 0;

//时间复杂度O(n)

//空间复杂度O(1)

为了更好的理解,请访问https://www.youtube.com/watch?v=thPG6eTPf68&t=130s

【讨论】:

以上是关于分而治之算法找到两个有序元素之间的最大差异的主要内容,如果未能解决你的问题,请参考以下文章

分而治之 - 在包含唯一元素的两个大小相等的数组之间找到中位数?

排序算法!

如何使用分而治之以及如果一个子阵列占多数,组合阵列占多数以找到多数元素的事实?

使用分而治之的最大连续和

归并排序之python

运行分而治之算法后从数组中打印最大子数组值