/** * A recursive divide-and-conquer solution to the Stock Market problem * * @author americachambers * */ public class Recursive implements StockIfc{ public StockInfo solve(int[] prices) { return recursive(prices, 0, prices.length-1); } /** * The main recursive method that divides the price array * in half and then merges the solutions to subproblems to * construct a solution to the original problem * * @param prices stock prices * @param left leftmost index into prices array under consideration * @param right rightmost index into prices array under consideration * @return solution to the Stock Market problem */ private StockInfo recursive(int[] prices, int left, int right) { // Our base case is a single day in which case we // buy, sell, and compute profit based on that day if(left >= right) { StockInfo s = new StockInfo(); s.buy_index = left; s.sell_index = left; s.max_index = left; s.min_index = left; s.profit = 0; return s; } // Divide the problem just like we do in Mergesort int mid = (right+left)/2; StockInfo fromLeft = recursive(prices, left, mid); StockInfo fromRight = recursive(prices, mid+1, right); return recursiveMerge(prices, fromLeft, fromRight); } /** * This method implements the merging of two subproblems into * a solution for the larger problem * * @param prices stock prices * @param fromLeft solution found for left subproblem * @param fromRight solution found for right subproblem * @return solution to the larger problem */ private StockInfo recursiveMerge(int[] prices, StockInfo fromLeft, StockInfo fromRight) { StockInfo s = new StockInfo(); // Compute best profit where we buy in left range and sell in right range int crossProfit = prices[fromRight.max_index]-prices[fromLeft.min_index]; // The cross profit provides the greatest profit if( crossProfit > fromLeft.profit && crossProfit > fromRight.profit){ s.buy_index = fromLeft.min_index; s.sell_index = fromRight.max_index; s.profit = crossProfit; } // The profit from the left is the greatest else if(fromLeft.profit > fromRight.profit) { s.buy_index = fromLeft.buy_index; s.sell_index = fromLeft.sell_index; s.profit = fromLeft.profit; } // The profit from the right is the greatest else{ s.buy_index = fromRight.buy_index; s.sell_index = fromRight.sell_index; s.profit = fromRight.profit; } // Take the minimum of the minimums if(prices[fromLeft.min_index] < prices[fromRight.min_index]) { s.min_index = fromLeft.min_index; } else { s.min_index = fromRight.min_index; } // Take the maximum of the maximums if(prices[fromLeft.max_index] > prices[fromRight.max_index]) { s.max_index = fromLeft.max_index; } else { s.max_index = fromRight.max_index; } return s; } }