股票问题
1.暴力求解 2. 分治法
题目解析:根据价格的变化,求出股票在哪天买入哪天卖出,收益会最大。
暴力求解:遍历每一个子数组区间,比较大小,并记录最大收益的开始和结束的下标
代码实现:
using System;
namespace cchoop
{
class Program
{
public static void Main()
{
int[] price = new int[] { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
int[] priceChange = new int[price.Length - 1];
for (int i = 1; i < price.Length; i++)
{
priceChange[i - 1] = price[i] - price[i - 1];
}
int sum = priceChange[0];
int startIndex = 0;
int endIndex = 0;
for (int i = 0; i < priceChange.Length; i++)
{
int tempSum = 0;
for (int j = i; j < priceChange.Length; j++)
{
tempSum += priceChange[j];
if (tempSum > sum)
{
startIndex = i;
endIndex = j;
sum = tempSum;
}
}
}
Console.WriteLine("最大收益为:{0},第{1}天买入,第{2}天卖出", sum, startIndex, endIndex + 1);
}
}
}
分治法
解题思路:将数组分成两份,最大子数组(元素之和最大)只有三种情况:
(1)最大子数组在mid左边,即:startIndex和endIndex都在mid左边
(2)最大子数组一半在左边,一半在右边,即:startIndex在 mid左边,endIndex在mid右边
(3)最大子数组在mid右边,即:startIndex和endIndex都在mid右边
那么比较三种情况下的最大子数组的结果接可以了,最终得出最大子数组
那么继续运用递归,继续给mid左边和右边进行分治求解,将复杂的问题进行简化,以此降低了代码的时间复杂度,提高了程序的运行效率。
代码实现:
using System;
namespace cchoop
{
class Program
{
public static void Main()
{
int[] price = new int[] { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
int[] priceChange = new int[price.Length - 1];
for (int i = 1; i < price.Length; i++)
{
priceChange[i - 1] = price[i] - price[i - 1];
}
MaxProfit maxProfit = GetMaxProfit(priceChange, 0, priceChange.Length - 1);
Console.WriteLine("最大收益为:{0},第{1}天买入,第{2}天卖出", maxProfit.ProfitNum, maxProfit.StartIndex, maxProfit.EndIndex + 1);
}
public static MaxProfit GetMaxProfit(int[] priceChange, int low, int high)
{
if (low == high)
{
MaxProfit maxProfit;
maxProfit.StartIndex = low;
maxProfit.EndIndex = high;
maxProfit.ProfitNum = priceChange[low];
return maxProfit;
}
int mid = (low + high) / 2;
//startIndex、endIndex都在mid左边
MaxProfit maxProfitLeft = GetMaxProfit(priceChange, low, mid);
//startIndex、endIndex都在mid右边
MaxProfit maxProfitRight = GetMaxProfit(priceChange, mid + 1, high);
//startIndex在mid左边,endIndex在mid右边
int startIndex = mid;
int endIndex = mid;
int totalProfit = priceChange[mid];
int tempProfit = 0;
//左边
for (int i = mid; i >= 0; i--)
{
tempProfit += priceChange[i];
if (tempProfit > totalProfit)
{
totalProfit = tempProfit;
startIndex = i;
}
}
//右边
tempProfit = totalProfit;
for (int i = mid + 1; i < priceChange.Length; i++)
{
tempProfit += priceChange[i];
if (tempProfit > totalProfit)
{
totalProfit = tempProfit;
endIndex = i;
}
}
MaxProfit maxProfitMid;
maxProfitMid.StartIndex = startIndex;
maxProfitMid.EndIndex = endIndex;
maxProfitMid.ProfitNum = totalProfit;
//比较 三个maxProfit
MaxProfit tempMaxProfit = maxProfitLeft;
if (maxProfitMid.ProfitNum > tempMaxProfit.ProfitNum)
{
tempMaxProfit = maxProfitMid;
}
if (maxProfitRight.ProfitNum > tempMaxProfit.ProfitNum)
{
tempMaxProfit = maxProfitRight;
}
return tempMaxProfit;
}
}
struct MaxProfit
{
public int StartIndex;
public int EndIndex;
public int ProfitNum;
}
}