1

Having an array A of integers with N elements for example {4, 2, 11, -2, 1} i need to find the element with max value from every sub array . Sub arrays are generated this way:

for i = 0, leftArray = {4} , rightArry = {2,11,-2,1} 
for i = 1, leftArray = {4,2}, rightArry = {11,-2,1}
for i = 2, leftArray = {4,2,11}, rightArry = {-2, 1}
for i = 3, leftArray = {4,2,11,-2}, rightArry {1}

So, i need something like this:

for (int i = 0; i < A.length; i++){
   //LOGIC HERE
    System.err.println(String.format("Left array max = %s, Right array max = %s",lmax, rmax));
}

This would't be a problem if we don't care about time-complexity, BUT expected worst-case time complexity is O(N)

I have not idea how to achive this with O(N) algorithm. Any help would be appreciated.

EDIT:

My current solution:

for (int i = 0; i < A.length; i++)
        {
            if(i  == A.length - 1)
                break;

            int[] l = Arrays.copyOfRange(A, 0, i + 1);
            int[] r = Arrays.copyOfRange(A, i + 1, A.length);

            Arrays.sort(l);
            Arrays.sort(r);
            System.err.println(l[l.length -1] + " " + r[r.length - 1]);
        }
16
  • 1
    What is your current solution and what is its complexity? Commented May 16, 2016 at 21:57
  • you have to generate the subarrays also? Commented May 16, 2016 at 21:58
  • Do you have to generate them in ascending order only? If not, you could do a loop with ascending i to get the max for leftArray, then a loop with descending i to get the max for rightArray. Commented May 16, 2016 at 22:04
  • 2
    @Arctigor O(2n) is the same as O(n) ... Or am I missing something here? Commented May 16, 2016 at 22:10
  • 1
    @Arctigor indeed, what YassinHajaj said. A constant multiple of O(n) is still O(n). Commented May 16, 2016 at 22:11

1 Answer 1

5

It's possible in O(n), but I can only think of how to do it in two passes to find the maxes, then another pass to print them:

int[] leftMaxes = new int[A.length - 1];
int[] rightMaxes = new int[A.length - 1];

leftMaxes[0] = A[0];
for (int i = 1; i < A.length - 1; ++i) {
  leftMaxes[i] = Math.max(leftMaxes[i-1], A[i]);
}

rightMaxes[A.length - 2] = A[A.length - 1];
for (int i = A.length - 3; i >= 0; --i) {
  rightMaxes[i] = Math.max(rightMaxes[i+1], A[i+1]);
}

for (int i = 0; i < A.length - 1; ++i) {
  System.out.printf("%d: %d %d%n", i, leftMaxes[i], rightMaxes[i]);
}

Ideone demo

Output:

0: 4 11
1: 4 11
2: 11 1
3: 11 1

You could combine the leftMaxes and printing loops (doing the rightMaxes first) to remove one of the passes; but that's not necessary for the required complexity.

And you could combine the rightMaxes and leftMaxes loops, but I think that would make the code a lot harder to read.

Sign up to request clarification or add additional context in comments.

3 Comments

@Andreas well, ok :) I wasn't counting that one because that's not actually finding the maxes.
@AndyTurner You new comment at the end of the answer, combining leftMaxes and printing would however eliminate the need for the leftMaxes array (using running max instead), reducing memory footprint, right?
@Andreas indeed it would.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.