2

My goal is to write down a function that calls all the even-numbered indices will have the largest numbers in the list in descending order and the odd-numbered indices will have the smallest numbers in ascending order.

For example:

input: arr = [1,2,3,4,5]
output: arr = [5,1,4,2,3]

input: arr = [1,2,3,4,5,6,7]
output: arr = [7,1,6,2,5,3,4]

I'm splitting the original array into two different arrays. One for the even-indexed and the other one for the odd-indexed. Then I reversed the array with even-indexed numbers. My problem is to merge two unequal lists alternatively.

# This is my python code

def max_min_naive(lst):
    even_lst = []
    odd_lst = []

    for i in range(len(lst)):
        if i%2 == 0:
            even_lst.append(lst[i])
        else:
            odd_lst.append(lst[i])
    #print(even_lst, odd_lst)
    even_lst.reverse()
    #print(even_lst, odd_lst)

    even_pointer = 0
    odd_pointer = 0
    res = []

    #print(len(even_lst), len(odd_lst))

    #This part is wrong. need help

    while len(res) <= len(lst):
        if even_pointer < len(even_lst):
            res.append(even_lst[even_pointer])
            even_pointer += 1
        else:
            break
        if odd_pointer < len(odd_lst):
            res.append(odd_lst[odd_pointer])
            odd_pointer += 1
        else:
            break
    #print(res)
    return res

if __name__ == '__main__':
    lst = [1,2,3,4,5]
    lst_1 = [1,2,3,4,5,6,7]
    print(max_min_naive(lst))
    print(max_min_naive(lst_1))

I get [7,2,5,4,3,6,1] instead of [7,1,6,2,5,3,4]

Jang
  • 53
  • 6

5 Answers5

3

Using some fancy helper methods

from itertools import chain, islice
...

arr = sorted(arr)
arr = list(islice(chain.from_iterable(zip(reversed(arr), arr)), len(arr)))
flakes
  • 21,558
  • 8
  • 41
  • 88
2

Two-liner:

arr = sorted(arr, reverse=True)
arr = [arr[-(i // 2 + 1)] if i % 2 else arr[i // 2] for i in range(len(arr))]

Basically, given a sorted array, you want to reorder it following: 0 -> 0; 1 -> -1; 2 -> 1; 3 -> -2; 4 -> 2; 5 -> -3

So even indices get arr[i // 2] and odd indices get arr[-(i // 2 + 1)].

Kefeng91
  • 802
  • 6
  • 10
1

A solution that separates the ascending and descending lists first then merges.

from itertools import chain, zip_longest

for arr in [
    [1,2,3,4,5], # 5 1 4 2 3
    [1,2,3,4,5,6], # 6 1 5 2 4 3
]:
    if len(arr) <= 1:
        print(arr)
        continue

    to_move_count = len(arr) // 2
    
    descending = list(reversed(arr[-to_move_count:]))
    ascending = arr[:len(arr) - to_move_count]
    
    merged = chain.from_iterable(zip_longest(descending, ascending))
    merged = list(filter(lambda value: value is not None, merged))
    print(merged)
[5, 1, 4, 2, 3]
[6, 1, 5, 2, 4, 3]
  • 1
    Fun fact, to filter out `None` values, you can just do: `list(filter(None, merged))` – flakes Sep 01 '21 at 04:25
  • 2
    Good to know! I didn't know that, thanks for the new learning. But for this case, since it would filter out "false" values, I tried and it also filtered out the number `0` in the list, which maybe unexpected. – Niel Godfrey Pablo Ponciano Sep 01 '21 at 04:29
1

See if this helps:

Instead of splitting it into 2 arrays, Here is a simple solution:

a=[1,2,3,4,5,6,7]
b=[]
for i in range(int(len(a)/2)):
    b.append(a[-1*(i+1)])
    b.append(a[i])
if(len(a)%2!=0):
    b.append(a[i+1])    
b
Subasri sridhar
  • 809
  • 5
  • 13
1

I would break this apart some more. First off we know that we want a sorted array, so lets do that:

arr = sorted(arr)

Then we can break the list into the high numbers and low numbers:

lower = arr[:len(arr) // 2]
upper = arr[len(arr) // 2:]

Now we want to populate a merged list. While there are items left, pop the higher from the end, and the lower from the start:

merged = []
while lower or upper:
    if upper:
        merged.append(upper.pop())
    if lower:
        merged.append(lower.pop(0))

You'll be left with the desired result in merged.

flakes
  • 21,558
  • 8
  • 41
  • 88
  • 1
    Thank you so much. I will keep the nested library solution above in my mind for the future. This solution looks so clean and so easy to understand. – Jang Sep 01 '21 at 13:55