在数组中返回一对数字p和q。 p必须出现在数组中的q之前,并且q-p必须是可能的最高值
A = [1,4,12,5,9,1,3,8]
返回值为p = 1& Q = 12
有人提出以下解决方案。 但是我不确定它应该在“第三种情况”中返回,如下所示:
建议:
将A均分为两个较小的数组A1,A2,并在A1和A2上解决问题(递归)。这可以帮助您找到A的最佳值吗?不要忘记你被允许使用额外的处理成本高达O(n)。假设p,q是A的最佳对。无论是p,q∈A1,还是p,q∈A2,或者这些都不是情况属实。关于p和q,你能在第三种情况下说些什么呢?
下面是我的代码,它基本上划分数组并从上半部分到最后部分从下半部分获得最小值。有0(n)解决方案,但我对递归的感兴趣,因为我正在学习递归。所以请不要提出任何其他解决方案。
#define min_f(a, b) (a)>(b)?(b):(a)
#define max_f(a, b) (a)>(b)?(a):(b)
#define MAX 1 << 30
#define MIN -1
int get_min(int *a, int start, int end)
{
int t_min = MAX;
while(start <= end) {
t_min = min_f(t_min, a[start]);
start++;
}
return t_min;
}
int get_max(int *a, int start, int end)
{
int t_max = MIN;
while(start <= end) {
t_max = max_f(t_max, a[start]);
start++;
}
return t_max;
}
int foo(int *a, int start, int end)
{
int g_max = MIN;
int min, max, i;
for(i=0;i<=end;i++) {
min = get_min(a, start, i);
max = get_max(a, i+1, end);
if (max > min) {
g_max = max_f(g_max, max-min);
}
}
return g_max;
}
int main()
{
int a[] = {1,4,12,5,9,1,3,8};
int size = sizeof(a)/sizeof(a[0]);
printf("%d\n", foo(a, 0, size-1));
return 0;
}
答案 0 :(得分:0)
您的递归解决方案只不过是Divide and Conquer algorithm.您还可以查找Binary-search algorithm以了解“分而治之”的基本概念。
现在,让我们举个例子。
time limit exceeding error.
如果您确实阅读了上述链接,或者您知道Divide and Conquer算法,您将理解我们递归地执行左子阵列和右子阵列的操作。下一步是,我们再次划分每一半。在这里,让我们只做前半部分,只需要进入第三种情况就足够了。
上半场,再分一次。
[1,4,12,5,9,1,3,8]
/\
/ \
/ \
[1,4,12,5] [9,1,3,8]
在分割阵列的这一步,您应该已经理解了第三种情况。答案p = 1(左半部分)和q = 12(右半部分)位于分割后不同的一半
这是第三种情况。现在,我让你为此编写递归代码并在代码中适当地处理第三种情况。
答案 1 :(得分:0)
可以先在递归函数中找到最大值,然后以相同的方式找到最小值。找到差异之后。我认为您无法通过一种功能来做到这一点。
public static int diff(int[] arr)
{
int max=findMax(arr, 0, arr.Length - 1);
int min=findMin(arr, 0, arr.Length - 1);
return max-min;
}
private static int findMax(int[] arr, int index_begin, int index_end)
{
if (index_begin == index_end) return arr[index_begin];
int m = (index_begin + index_end) / 2;
return Math.Max(findMax(arr, index_begin, m), findMax(arr, m + 1,
index_end));
}
private static int findMin(int[] arr, int index_begin, int index_end)
{
if (index_begin == index_end) return arr[index_begin];
int m = (index_begin + index_end) / 2;
return Math.Min( findMin(arr, index_begin, m), findMin(arr, m + 1,
index_end));
}