How to optimize this method in Java? I am getting time Limit Exceed

theUturn :

I have two Lists, one has the index of elements and the other has the stock prices. For each index I have to find the minimum and nearest stock price upwards or downwards in the stock array whichever is smaller than the stock price at the current index and nearest. Here is my code. It is accurate but is too slow so gives a Time Limit execution error;

public static List<Integer> predictAnswer(List<Integer> stockData, List<Integer> queries) {
    List<Integer> resQuery = new ArrayList<>();

    /* to show -1 if there is no such stock price */
    for (int i = 0; i < queries.size(); i++) {
        resQuery.add(-1);
    }

    for (int i = 0; i < queries.size(); i++) {
        /* the query index starts from 1 or supposes the first index is 1 */
        int index = (int) (queries.get(i) - 1);
        int value = stockData.get(index).intValue();

        int j = index + 1;
        int k = index - 1;

        while (j < stockData.size() - 1 || k > 1) {

            if (k < 1) {
                if (stockData.get(j).intValue() < value) {
                    resQuery.set(i, j + 1);
                    break;
                }
            } 

            else if (j > stockData.size() - 1) {
                if (stockData.get(k).intValue() < value) {
                    resQuery.set(i, k + 1);
                    break;
                }
            } 

            else if (stockData.get(k).intValue() < value) {
                resQuery.set(i, k + 1);
                break;
            } 

            else if (stockData.get(j).intValue() < value) {
                resQuery.set(i, j + 1);
                break;
            }

            j++;
            k--;
        }
    }
}

Can you help me to refactor this code in order to improve the performances?

Sarmon :

It seems that your algorithm has O(n^2) time complexity. There are two classical methods to solve such problems in O(n). The first one using a stack and the second one using dynamic programming.

I suggest an example to explain what is not good in your algorithm.

Suppose you have [1, 4, 3, 2] as stock prices.

For the third element 3, it will iterate over 4 and then 1 to find the nearest smaller downwards.

For the last element 2, it will iterate over 3, 4 and then 1 to find the nearest smaller downwards. So it does not take into account the work you have done before with 3 (it ignores the fact that you don't have to iterate over 4 because it is greater than 3 so greater than 2). If you have many consecutive 4, it will iterate over all of them rather than jumping directly to 1.

The purpose of the algorithm with dynamic programming is to take into account the work you have done before. It uses an array to store the index of nearest smaller downwards for each stock price. With the example above, The final version of this array will be [-1, 0, 0, 0] (1 does not have a nearest smaller downwards so we represent it by -1, the nearest smaller for the others is 1 which is in index 0).

To compute this array, you initialize it by [-1, -1, -1, -1]. For example, when processing the last element you will have [-1, 0, 0, -1]. You compare it to 3 and find that 3 is greater so you jump directly to the nearest smaller of 3 which is in index 0. You then compare your element to the element in index 0 (which is 1). 1 is smaller so you find the nearest smaller...

And you can do the same thing for nearest smaller upwards.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=25315&siteId=1