function that returns the last met of each numbers in a sorted array

我与影子孤独终老i 提交于 2021-02-05 06:52:30

问题


I wrote a function that returns the first met of each numbers from 0 to 9

array = [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9]


def lower(a, val, left, right):
    if left == right:
        return left
    mid = (left + right) // 2

    if a[mid] < val:
        return lower(a, val, mid+1, right)
    else:
        return lower(a, val, left, mid)

for i in range(10):
    print(lower_bound(array, i , 0, len(array)-1), end =' ')   

result: 0 2 4 6 8 10 12 14 16 18 .

I tried to write a function that return the last met of each numbers from 0 to 9. and wanted to get: 1 3 5 7 9 11 13 15 17 19

But it does not works correctly( could you help me to with it? Here is my function.

def upper(a, val, left, right):

    if left == right:
        return left
    mid = (left + right) // 2

    if a[mid] <= val:
        return upper(a, val, mid+1, right)
    else:
        return upper(a, val, left, mid)

回答1:


You need to return left-1 instead of left. This is because when you arrive at the last index of val mid, the first if will look from mid+1 (upper(a, val, mid+1, right))

def upper(a, val, left, right):

    if left == right:
        return left-1
    mid = (left + right) // 2

    if a[mid] <= val:
        return upper(a, val, mid+1, right)
    else:
        return upper(a, val, left, mid)




回答2:


The reason is that in every case that you are in the last occurrence and the right is one index after, you find the appropriate index but keep moving one more step. the algorithm seems to be good, but just eliminate this case and everything works fine:

array = [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9]

def upper(a, val, left, right):

    if left == right:
        if a[left] == val:
            return left
        else:
            return left-1
    mid = (left + right) // 2
    if a[mid] <= val:
        return upper(a, val, mid+1, right)
    else:
        return upper(a, val, left, mid)
        

for i in range(10):
    a = upper(array,i,0,19)
    print(a)

output:

1
3
5
7
9
11
13
15
17
19

checked it for several others and it works fine I think




回答3:


To find the first met:

for i in range(10):
  print(array.index(i))

To find the last met:

inverted_array = array[::-1]
for i in range(10):
  print(len(array) - 1 - inverted_array.index(i))



回答4:


Using the floor function when calculating mid means the function is not symmetrical. You can't just mirror one part of it without considering the other.

def upper(a, val, left, right):
    if left == right:
        return left
    mid = (left + right + 1) // 2

    if a[mid] > val:
        return upper(a, val, left, mid-1)
    else:
        return upper(a, val, mid, right)


来源:https://stackoverflow.com/questions/64082509/function-that-returns-the-last-met-of-each-numbers-in-a-sorted-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!