遇到個簡單的算法題,沒有當場解出來,以后可以寫偽代碼表達思路。
數組中保存每天的股票價值,求買入賣出的時間和最大利潤,比較好的解法如下:
偽代碼:
begin
start day = 0; end day = 0; max value = 0;
for day 1 to N;
value = next day's value - today's value;
if value > 0
get max value and day;
else if value < 0
today = next day;
end
實際編碼:
#define N 10 int value[N] = { 5, 8, 3, 9, 10, 4, 5, 14, 2, 7 }; void GetMaxValue(int * start, int * end, int * max) { int curr_day = 0, next_day = 0, tmp_max = 0; for (next_day = 1; next_day < N && curr_day < N; next_day++) { tmp_max = value[next_day] - value[curr_day]; if (tmp_max > *max)//保存比較大的利潤和買賣日期 { *max = tmp_max; *start = curr_day; *end = next_day; } else if (tmp_max < 0)//后一天股票值比今天低,可能存在更高利潤,作為新起點計算 { curr_day = next_day; } } printf("start_day:%d , end_day:%d ,max_value:%d \n", *start, *end, *max); }
思路:
自己的第一印象是兩個循環,先求出每天買入可得的最大利潤,然后再循環一次獲取最大的利潤,這種是復雜度最高的,里面存在重復計算,當時沒有想到優化的辦法。后來仔細想了想,用一個循環完全可以解決,思路如下:
從第一天開始,第二天的股票值如果比今天高,那就保存買賣日期和利潤,這樣繼續下去肯定能得到今天買入的最大利潤及賣出日期。並且,后面比今天價格高的日期根本不需要計算,因為利潤肯定沒今天高。
也就是說只需要這一個循環,后面價格高的統統排除掉了。
如果后面某天價格比今天低呢,那就可能存在更大的利潤了,所以現在當前計算的日期不需要繼續計算,用低價日作為新的起點。因為假如后面有高價日,那今日賣出的利潤也沒低價日賣出的高。
然后就是重復計算新低價日期能獲得的最佳結果,跟舊結果比,取最優值。