在你的問題的問題都可以轉化爲一個更好的問題陳述的例子:
由於股票價格的每一天對於n天,通過完成一次交易,一個人可以獲得的最大利潤是多少。一筆交易意味着該人可以在一天內買入一隻股票,並在稍後的日期賣出。
分而治之的解決方案:讓我們看看我們是否能夠通過拆分輸入了一半,每個子陣列解決這個問題,那麼兩者結合起來解決這個問題。事實證明,我們實際上可以做到這一點,並且可以高效地做到!直覺如下。如果我們有一天的時間,最好的選擇是當天買入,然後在同一天賣出,無利可圖。否則,將數組分成兩半。如果我們考慮最佳答案可能是什麼,它必須位於三個位置之一:
- 正確的買入/賣出對在上半部分完全發生。
- 正確的買入/賣出對在下半年完全發生。
- 正確的買入/賣出對發生在兩個半部分 - 我們在上半年買入,然後在下半年賣出。
我們可以通過在第一和第二半上遞歸地調用我們的算法來獲得(1)和(2)的值。對於期權(3)而言,獲得最高利潤的方法是在上半年的最低點買入,並在下半年賣出最高點。通過對輸入進行簡單的線性掃描並找到兩個值,我們可以在兩半中找到最小值和最大值。然後這給了我們一個算法,下面的重現:
T(n) = 2T(n/2) + O(n)
T(n) = O(nlogn)
這是一個簡單的Python實現。它非常簡單易懂,它也很容易轉換爲C++:
def DivideAndConquerSingleSellProfit(arr):
# Base case: If the array has zero or one elements in it, the maximum
# profit is 0.
if len(arr) <= 1:
return 0;
# Cut the array into two roughly equal pieces.
left = arr[ : len(arr)/2]
right = arr[len(arr)/2 : ]
# Find the values for buying and selling purely in the left or purely in
# the right.
leftBest = DivideAndConquerSingleSellProfit(left)
rightBest = DivideAndConquerSingleSellProfit(right)
# Compute the best profit for buying in the left and selling in the right.
crossBest = max(right) - min(left)
# Return the best of the three
return max(leftBest, rightBest, crossBest)
編輯:這裏是上述算法
#include <iostream>
#include <algorithm>
using namespace std;
int calculateMin(int a[], int low, int high)
{
int i,mini;
mini = a[low];
for(i=low;i<=high;i++)
{
if(a[i]<mini)
{
mini = a[i];
}
}
return mini;
}
int calculateMax(int a[], int low, int high)
{
int i,maxi;
maxi = a[low];
for(i=low;i<=high;i++)
{
if(a[i]>maxi)
{
maxi = a[i];
}
}
return maxi;
}
int calculateMaxDiff(int a[], int low, int high)
{
if(low>=high)
return 0;
int mid = (low+high)/2;
int leftPartition = calculateMaxDiff(a,low,mid);
int rightPartition = calculateMaxDiff(a,mid+1,high);
int left = calculateMin(a,low,mid); // calculate the min value in the left partition
int right = calculateMax(a,mid+1,high); // calculate the max value in the right partition
return max(max(leftPartition, rightPartition), (right - left));
}
int main() {
int arr[] = {12, 9, 18, 3, 7, 11, 6, 15, 6, 1 ,10};
int len = sizeof(arr)/sizeof(arr[0]);
int ans = calculateMaxDiff(arr, 0, len-1);
cout << "Maximum Profit: " <<ans<<endl;
return 0;
}
希望它可以幫助C++實現!
這是什麼甚至試圖實現?你有樣品使用情況和預期結果嗎? – tadman
@tadman我添加了一個示例輸出 – RRP
所以你需要計算整個數組的最大*和*最小值。這裏不需要遞歸,只需要兩個變量和一個迭代循環。事實上,我不認爲你可以(有效地)用遞歸來解決這個問題。 – tadman