1. Starting with the question of a stock price
If you have the ability to predict a company's share price in the future. Is your forecast of the stock price, then which day you will buy, which day to sell?
You might think that you can buy it on the day of the lowest share price in 17 days (the 7th day) and then sell it on the day after the stock price is the highest (the 11th day), or in turn sell the day after the highest price for the entire period, and then buy it the day before the stock price is the lowest. If this strategy is feasible, it would be very easy to determine the maximum benefit. But this strategy is not always effective. For example, this situation:
It is easy to see that buying on the 2nd day and selling on the 3rd day will get the most benefit. But the next day was not the lowest (in fact the stock price was the 4th day) and the 3rd day was not the highest (the price was the highest of 1th days).
2. Methods of violence (exhaustive method exhaustive) solution
The easiest way we can think of is a brute force solution (in fact, when conditions allow, brute force is a good way). By analyzing this method, we can find that the combination we need to try in n days is kind of, and the time to process each pair of dates is at least constant time, so this method runs at θ (N2). The Java implementation code for this algorithm is given below:
Public Static voidMain (string[] args) {int[] Pricearray =New int[] {//100, 113, 110, 85,//105, 102, 86, 63,//81, 101, 94, 106,//101, 79, 94, 90,//97};intMaxdifference = Integer.min_value;intStartDay =-1;intEndday =-1; for(inti = 0; i < pricearray.length; i++) {intStartPrice = Pricearray[i]; for(intj = i + 1; J < Pricearray.length; J + +) {intEndprice = Pricearray[j];intdifference = Endprice-startprice;if(Difference > Maxdifference) {maxdifference = Difference;startday = I;endday = J;}}} System.out.println ("Section"+ StartDay +"Day Buy, first"+ Endday +"days to sell for maximum spreads:"+ maxdifference);}
Running Result: 7th day buy, 11th day sell to get the maximum difference: 43
3. Maximum sub-array problem
The exhaustive approach (exhaustive method) is simple, but often not optimal. Is there a better way to do that?
We look at the input data from a slightly different perspective. Our aim is to look for a period of time, making the net change in the price of the first day to the last day the biggest. So instead of looking at the input data from the daily price point of view, we look at the daily price changes. If a change in the daily price is set to an array of arrays, for example, then the problem becomes: Find a sub-array (the largest subarray) in the array, making the sum of all the elements of the sub-array the largest .
At first glance, the transformation of this problem does not bring us any benefits. If the brute force method is used for a period of N days, we still have to check the times, and the operation time is still θ (N2).
Next, we look for a more efficient way to find the maximum subarray. It is important to note that the maximum number of sub-arrays may sometimes be multiple, and it makes sense to discuss the maximum subarray problem only if the array contains negative elements, because the entire array is necessarily the largest subarray for non-negative groups.
4. Solving the maximal subarray using the divide-and-conquer method (Divide and Conquer)
In the first article we have been exposed to over-treatment strategies, which need to consider the following three steps:
① decomposition: decomposition means that we want to divide the array into two sub-arrays of the same scale as possible. In other words, if the array A[low~high] is the array to be solved, we will divide A[low~high] into A1[low~mid],a2[mid~high], where mid = (High–low)/2.
② Solution: The solution means that we want to solve the sub-array recursively. It is important to note that the maximum number of sub-arrays may be in the following three situations: in A1; in a2; across the midpoint.
③ Merge: a true maximum subarray is obtained by comparing the largest sub-arrays found in the above three cases.
The following is a Java implementation code for the divide-and- Divide Method (Conquer) :
/** * Divide and conquer law * * @param args * * Public Static voidMain (string[] args) {int[] Differencearray =New int[] {//13,-3,-25,-20,//-3,-16,-23, 18,//20,-7, 12,-5,//-22, 15,-4, 7,//}; Result result = Findmaxsubarray (Differencearray, 0, differencearray.length-1); System.out.println ("Section"+ Result.startday +"Day Buy, first"+ Result.endday +"days to sell for maximum spreads:"+ result.maxdifference);}/** * Find the maximum subarray * * @param array * @return */Private StaticResult Findmaxsubarray (intArray[],intLowintHigh) {if(Low = = high) {Result result =NewResult (); result.startday = Low;result.endday = Low;result.maxdifference = Array[low];returnResult;}Else{Result Leftresult = Findmaxsubarray (Array, low, (high + Low)/2); Result Rightresult = Findmaxsubarray (array, (high + low)/2 + 1, high); Result Crossingmiddleresult = findmaxsubarraycrossingmiddle (array, low, high);intMaxdifference = Math.max (Math.max (Leftresult.maxdifference, rightresult.maxdifference), Crossingmiddleresult.maxdifference);if(maxdifference = = leftresult.maxdifference) {returnLeftresult;}Else if(maxdifference = = rightresult.maxdifference) {returnRightresult;}Else{returnCrossingmiddleresult;}}}/** * Find the largest sub-array across the midpoint * */Private StaticResult Findmaxsubarraycrossingmiddle (int[] Array,intLowintHigh) {Result result =NewResult ();intMaxleftsum = Integer.min_value;intMaxrightsum = Integer.min_value;intsum = 0;intMid = (high + low)/2; for(inti = mid; I >= 0; i--) {sum + = Array[i];if(Sum > Maxleftsum) {maxleftsum = Sum;result.startday = i;}} sum = 0; for(inti = mid; i < Array.Length; i++) {sum + = Array[i];if(Sum > Maxrightsum) {maxrightsum = Sum;result.endday = i;}} Result.maxdifference = Maxleftsum + maxrightsum;returnResult;}Static classResult { Public intStartDay; Public intEndday; Public intMaxdifference;}
The result is: Buy on the 7th day and sell on the 11th day to get the maximum difference: 43
Let's set up a recursive procedure to describe the time of the recursive process.
① the basic casefor low = high, which takes a constant time θ (1).
② for Low≠hight recursion (recursive case), two recursion takes 2T (N/2) time, Findmaxsubarraycrossingmiddle method takes time θ (n), the remainder spends constant time θ (1) , therefore altogether costs 2T (N/2) +θ (1). That
Solution to T (n) =θ (NLGN). When n is large, the method will defeat the brute-lifting method (exhaustive).
5. Another time is a linear method
Let's consider a method that extends from the leftmost part of the array to the right, and records the largest sub-array in the extended process. If the largest subarray of Array[0~j] is known, expand the solution to the largest subarray of Array[0~j+1] based on the following method: Array[0~j+1] The largest sub-array of either array[0~j], or array[i~j+1] (0≤i≤j+ 1). In the case of the largest subarray of known Array[0~j], the largest subarray of shapes such as array[i~j+1] can be found within linear time.
PS: all of these are excerpted from the Chinese translation of the introduction to algorithms. I just extracted the article personally think that the more important points added some personal understanding for reference only.
Introduction to divide and conquer strategy-algorithm (3)