Sorting algorithm using divide and conquer - algorithm

This is like a stock marketing problem, I am confused that the question is asking about how to get everyday's maximum profit? I only know that the algorithm's time complexity can be O(n) or O(n log2 n).
The input is A, an array of stock prices. For day i, the best trade is the maximum profit that can be achieved by buying at day i and selling on a subsequent day. For convenience, you can define the best trade for the last day to simply be −A[n] (because if you buy on the last day, you cannot sell and you lost all your money).
Give the pseudocode of an algorithm that returns an array containing the maximum profit for every day in A.
Update: I understand how to get the maximum profit now, and I can use the similar algorithm as the merge sort that divide and conquer to find this maximum profit. My question is what's another method (algorithm) that use time complexity O(n) to find the maximum profit or how can I approach in this way?

One way you can think of this problem is using one for loop since it's O(n), I can give you some hints:
for i from 0 to n:
if (A[i] < A[min]) // find the minimum value of stock
min = i;
profit = A[i] - A[min] // get the profit
if (profit > maxProfit) { // compares the profits
maxProfit = profit // always update the max profit

If you buy on day i, the maximum profit you can make is Amax(i) - A[i],
where Amax(i) is the highest price that occurs after day i.
My reading of the algorithm's specification is that you are to construct and return the array M whose entries are defined by M[i] = Amax(i) - A[i].
The highest price that occurs after day i is the greater of
A[i+i] and the highest price that occurs after day i + 1.
The last paragraph gives you a recursive relationship, except that unlike
the "typical" recursion you might see, the ith value depends on the
i + 1st value rather than the other way around.
But fortunately for you, you already know that the nth value and
every later value is 0, that is, after day n you will get 0 for your stock.
So you only need to figure out the values for days
1, 2, ..., n - 1, which you can do in O(n) time.
And each time you find one of these values, Amax(i), you can set one of the entries of M using M[i] = Amax(i) - A[i].
If you want to find the maximum profit that can be made by buying one share of stock on any single day and selling on any subsequent day, one time
(though this is not required by the problem statement, as far as I can see), you just have to find the maximum value in M, which you can do in O(n) time.
If your goal is to make the maximum profit possible by a series of actions, buying and selling stock, the best you can do is to buy as many shares as you can afford whenever the stock is at a local minimum (assuming infinite price before the first day) and sell everything whenever it reaches a local maximum price. You can identify all the local minimums and maximums in O(n) time, scanning A in either direction, and given a starting amount of money, you can compute the maximum overall profit in O(n) time using the list of local minimums and maximums of A. (But this does not use the array that the original problem statement asked you to construct, because that array does not account for the number of shares bought nor the possibility of multiple transactions.)
Remember that if each pass of a two-pass algorithm takes O(n) time, the algorithm as a whole takes O(n) time.

Related

Finding minimum cost - An apple a day

We're given an array containing the prices of apples through N days.
After an apple has been brought, it needs to be consumed within D days.
Another constraint is that we can consume ONLY 1 apple a day.
So we have to find a balance between buying apples when the price is cheap, but also not buying too many that it will be spoiled in D days, and we won't be able to consume them all.
Can anyone suggest which algorithm could be the best for an optimal outcome?
Edit :- Yes, it's necessary to consume an apple a day, and only 1 apple a day.
To optimize expenses, we need to know minimum in sliding window of length K, ending in every day.
There is O(N) algorithm providing needed results using deque data structure.
Python code. Commented mins list contains indices of minimum value in window (for reference). Every day we increment count for the day with the cheapest price in period of K days.
from collections import deque
def mininslidingwindow(A, k):
#mins = []
buys = [0] * len(A)
deq = deque()
for i in range(len(A)):
if (len(deq) > 0) and (deq[0] <= i - k):
deq.popleft() #too old index
while len(deq) > 0 and A[deq[-1]] >= A[i]:
deq.pop() #remove elements having no chance to become a minimum
deq.append(i)
#mins.append(deq[0]) #deque head is current min
buys[deq[0]] += 1
return buys
print(mininslidingwindow([2,1,5,7,2,8,4,3,4,2], 3))
>>[1, 3, 0, 0, 3, 0, 0, 2, 0, 1]
Assumption: Assuming we need to eat an apple everyday.
A)
Algorithm Steps:
Preprocess spans of prices to know till what number of days the price on day i will be minimum in future. This process can be done in O(N) for all N days, where N is total days for which we want to plan.
Once we have the span till future for all days, we can greedily buy apples on day i keeping in mind the constraint of D days. At each day we will see if we can extend the number of days we have covered and buy as many apples required for those days. We extend only if the price at a given day is minimum for such days. This process involves scanning of N days. Hence O(N) time.
Time Complexity: The above problem could be solved in O(N) time where N is number of days of data provided.
Space Complexity: O(N) for the spans.
B) Better Algorithm for real time: Maintain a datastructure to keep data of past d days and returns minimum element. Buy an apple every day with minimum price following the criteria of being within d days else discard the price from the datastructure. Time complexity: O(N), Space Complexity: O(D)

Average subset of time series in real time

Suppose there is a real time feed of stock prices, how do you calculate the average of a subset of it (say over the past week)?
This was an interview question. I can come up with an algorithm to do it in O(n^2), but the interviewer wanted an algorithm that was O(n).
A useful approach is to compute the cumulative sum of your array.
This means that each entry in the cumulative sum array is the sum of all previous prices.
This is useful because you can then generate the sum over any particular subarray of your input using a single subtraction.
Note that when a new input arrives, you only need 1 addition to compute the new cumulative sum (because you simply add the new element to the old cumulative sum).
Another approach is akin to computing skew in Genomics.
If you want to compute the average over the past week, create a variable that contains the sum over a moving window. When an entry is created, add the entry to the above sum variable, and subtract the oldest entry in the moving window from it. Since the size of the window is constant, the average over the past week is just the moving sum over the number of entries in the past week.

Given a big list of items with a price and a value, choose the cheapest combination of 10 items with an average value greater or equal to a fixed val

I'm not a computer science major, so I have fairly limited knowledge of algorithms. Lately I was thinking of a market bot of some sort and I have a key question that I cannot handle with brute-force.
Question: Let there be a list of items, where number of items are greater
than 10000. Each item has a value in between 0 and 1, and a price. Value and
price are independent of each other. You must choose the cheapest 10 items
where their average (or total) value is greater or equal than a given value.
I thought of several algorithms such as:
-Sort the list by price
-Divide the list in 5 item chunks, reducing the brute
force steps from 10000nCr10 to 2000nCr2.
Obviously it will not give the true cheapest combination, but hopefully close enough? I appreciate any help.
You can solve it using integer linear programming. Let the value of item i be v[i] and its cost c[i]. Let x[i] be the number of each item you buy (which can take the values 0 or 1), and V be the minimum acceptable total value. The 0/1 constraint on x[i] makes this an integer linear program rather than a simpler linear program.
Then you want so minimize sum(c[i]*x[i]) such that sum(v[i]*x[i]) >= V and sum(x[i]) = 10, which is a problem of the right form to be solved as an ILP.
Here's a good open-source solver: https://www.gnu.org/software/glpk/

If you know the future prices of a stock, what's the best time to buy and sell?

Interview Question by a financial software company for a Programmer position
Q1) Say you have an array for which the ith element is the price of a given stock on
day i.
If you were only permitted to buy one share of the stock and sell one share
of the stock, design an algorithm to find the best times to buy and sell.
My Solution :
My solution was to make an array of the differences in stock prices between day i and day i+1 for arraysize-1 days and then use Kadane Algorithm to return the sum of the largest continuous sub array.I would then buy at the start of the largest continuous array and sell at the end of the largest
continous array.
I am wondering if my solution is correct and are there any better solutions out there???
Upon answering i was asked a follow up question, which i answered exactly the same
Q2) Given that you know the future closing price of Company x for the next 10 days ,
Design a algorithm to to determine if you should BUY,SELL or HOLD for every
single day ( You are allowed to only make 1 decision every day ) with the aim of
of maximizing profit
Eg: Day 1 closing price :2.24
Day 2 closing price :2.11
...
Day 10 closing price : 3.00
My Solution: Same as above
I would like to know what if theres any better algorithm out there to maximise profit given
that i can make a decision every single day
Q1 If you were only permitted to buy one share of the stock and sell one share of the stock, design an algorithm to find the best times to buy and sell.
In a single pass through the array, determine the index i with the lowest price and the index j with the highest price. You buy at i and sell at j (selling before you buy, by borrowing stock, is in general allowed in finance, so it is okay if j < i). If all prices are the same you don't do anything.
Q2 Given that you know the future closing price of Company x for the next 10 days , Design a algorithm to to determine if you should BUY,SELL or HOLD for every single day ( You are allowed to only make 1 decision every day ) with the aim of of maximizing profit
There are only 10 days, and hence there are only 3^10 = 59049 different possibilities. Hence it is perfectly possible to use brute force. I.e., try every possibility and simply select the one which gives the greatest profit. (Even if a more efficient algorithm were found, this would remain a useful way to test the more efficient algorithm.)
Some of the solutions produced by the brute force approach may be invalid, e.g. it might not be possible to own (or owe) more than one share at once. Moreover, do you need to end up owning 0 stocks at the end of the 10 days, or are any positions automatically liquidated at the end of the 10 days? Also, I would want to clarify the assumption that I made in Q1, namely that it is possible to sell before buying to take advantage of falls in stock prices. Finally, there may be trading fees to be taken into consideration, including payments to be made if you borrow a stock in order to sell it before you buy it.
Once these assumptions are clarified it could well be possible to take design a more efficient algorithm. E.g., in the simplest case if you can only own one share and you have to buy before you sell, then you would have a "buy" at the first minimum in the series, a "sell" at the last maximum, and buys and sells at any minima and maxima inbetween.
The more I think about it, the more I think these interview questions are as much about seeing how and whether a candidate clarifies a problem as they are about the solution to the problem.
Here are some alternative answers:
Q1) Work from left to right in the array provided. Keep track of the lowest price seen so far. When you see an element of the array note down the difference between the price there and the lowest price so far, update the lowest price so far, and keep track of the highest difference seen. My answer is to make the amount of profit given at the highest difference by selling then, after having bought at the price of the lowest price seen at that time.
Q2) Treat this as a dynamic programming problem, where the state at any point in time is whether you own a share or not. Work from left to right again. At each point find the highest possible profit, given that own a share at the end of that point in time, and given that you do not own a share at the end of that point in time. You can work this out from the result of the calculations of the previous time step: In one case compare the options of buying a share and subtracting this from the profit given that you did not own at the end of the previous point or holding a share that you did own at the previous point. In the other case compare the options of selling a share to add to the profit given that you owned at the previous time, or staying pat with the profit given that you did not own at the previous time. As is standard with dynamic programming you keep the decisions made at each point in time and recover the correct list of decisions at the end by working backwards.
Your answer to question 1 was correct.
Your answer to question 2 was not correct. To solve this problem you work backwards from the end, choosing the best option at each step. For example, given the sequence { 1, 3, 5, 4, 6 }, since 4 < 6 your last move is to sell. Since 5 > 4, the previous move to that is buy. Since 3 < 5, the move on 5 is sell. Continuing in the same way, the move on 3 is to hold and the move on 1 is to buy.
Your solution for first problem is Correct. Kadane's Algorithm runtime complexity is O(n) is a optimal solution for maximum subarray problem. And benefit of using this algorithm is that it is easy to implement.
Your solution for second problem is wrong according to me. What you can do is to store the left and right index of maximum sum subarray you find. Once you find have maximum sum subarray and its left and right index. You can call this function again on the left part i.e 0 to left -1 and on right part i.e. right + 1 to Array.size - 1. So, this is a recursion process basically and you can further design the structure of this recursion with base case to solve this problem. And by following this process you can maximize profit.
Suppose the prices are the array P = [p_1, p_2, ..., p_n]
Construct a new array A = [p_1, p_2 - p_1, p_3 - p_2, ..., p_n - p_{n-1}]
i.e A[i] = p_{i+1} - p_i, taking p_0 = 0.
Now go find the maximum sum sub-array in this.
OR
Find a different algorithm, and solve the maximum sub-array problem!
The problems are equivalent.

Greedy Algorithm Optimization

I have the following problem:
Let there be n projects.
Let Fi(x) equal to the number of points you will obtain if you spent
x units of time working on project i.
You have T units of time to use and work on any project you would
like.
The goal is to maximize the number of points you will earn and the F functions are non-decreasing.
The F functions have diminishing marginal return, in other words spending x+1 unit of time working on a particular project will yield less of an increase in total points earned from that project than spending x unit of time on the project did.
I have come up with the following O(nlogn + Tlogn) algorithm but I am supposed to find an algorithm running in O(n + Tlogn):
sum = 0
schedule[]
gain[] = sort(fi(1))
for sum < T
getMax(gain) // assume that the max gain corresponds to project "P"
schedule[P]++
sum++
gain.sortedInsert(Fp(schedule[P] + 1) - gain[P])
gain[P].sortedDelete()
return schedule
That is, it takes O(nlogn) to sort the initial gain array and O(Tlogn) to run through the loop. I have thought through this problem more than I care to admit and cannot come up with an algorithm that would run in O(n + Tlogn).
For the first case, use a Heap, constructing the heap will take O(n) time, and each ExtractMin & DecreaseKey function call will take O(logN) time.
For the second case construct a nXT table where ith column denotes the solution for the case T=i. i+1 th column should only depend on the values on the ith column and the function F, hence calculatable in O(nT) time. I did not think all the cases thoroughly but this should give you a good start.

Resources