2

I have been asked an interview question to reverse an array. I used the following method and it worked as expected:

def reverse(array, i, j):
  if i > j: # ensure i <= j
    i, j = j, i
  while i < j:
    array[i], array[j] = array[j], array[i]
    i += 1
    j -= 1 

Now, the interviewer asked me to replace the above while loop by for and I was really confused. Please can someone help me here. Thanks in advance.

7
  • 9
    but, why? array[i:j] = array[j:i:-1] Commented Jul 13, 2017 at 6:58
  • 1
    Or, array[i:j] = array[i:j][::-1] Commented Jul 13, 2017 at 7:04
  • 3
    @DeepSpace: Careful, it needs to be array[i:j] = array[j-1:i-1:-1]. For a = list(range(10)), a[4:8] = a[8:4:-1] gives you [0, 1, 2, 3, 8, 7, 6, 5, 8, 9]! Commented Jul 13, 2017 at 7:08
  • 1
    Why are so many people agreeing on the wrong answer Commented Jul 13, 2017 at 7:12
  • 2
    @xyres: Did you look at a after the operation? What you're quoting is just the slice a[8:4:-1], not the result of the replace operation. Commented Jul 13, 2017 at 7:33

4 Answers 4

3

This is not a for, but you can also do this:

If you follow the python logic where [i:j] means i <= x < j then you can do this:

array[i:j] = array[j-1:i-1:-1]

Other way, if you want to get the elements where i <= x <= j then you can do as @darksky suggested:

array[i:j+1] = array[j: i - 1: -1]
Sign up to request clarification or add additional context in comments.

3 Comments

This is still incorrect. This reverses the sub array with indices [i, j - 1], not [i, j]. It should be a[i:j+1] = a[j: i - 1: -1].
@darksky Well, that depends if you considered the j index to be inclusive or exclusive. My solution works when it's exclusive as it's in the python. If you want it to be inclusive then yes, your solution is correct. I will expand my answer.
Sure. That's fair enough.
1

You could forget the for loop entirely and do something like this:

def reverse(array, i, j):
    # Make sure i is less than j
    if i > j:
        i, j = j, i
    # Reverse array[i:j+1]
    section = array[i:j+1]
    section.reverse()
    array[i:j+1] = section

(The j+1 is to keep consistent with your function's behaviour; both i and j are treated as inclusive, but Python wants [inclusive, exclusive).)

Or if you want to keep the for loop in and avoid standard functions, then you could do something like this:

def reverse(array, i, j):
    # Make sure i is less than j
    if i > j:
        i, j = j, i
    # Reverse array[i:j]
    count = j - i + 1
    for offset in range(0, count // 2):
        first = i + offset
        second = j - offset
        array[first], array[second] = array[second], array[first]

Comments

1

Other answers here perform this in a really smart way, but a for loop should look something like:

for x in range(j - i):
    array[i+x], array[j-x] = array[j-x], array[i+x]

6 Comments

Does not give desired result
@deep it works for me, provided that i < j Plus, it's the only answer that provides you with a for loop which is what you asked for. Using the implementation exactly as above, but returning array gives: rev([1,2,3,4,5], 1, 3) [1,4,3,2,5] which is as expected.
@Baldrickk Thanks. But if i == j, shouldn't there be no reversal at all to be done?
@SamChats correct - I was instead inferring that if j < i (two valid indicies, but largest first), it will do no work - not that that is a problem with your loop, I would expect a function written using it to check and swap the values as part of the initial parameter checks.
@Baldrickk Yes, but the OP has already done that in his function.
|
0

I think more readable example would be:

arr[i,j] = reversed(arr[i, j])

Comments

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.