Find the second smallest number in a list using recursion

后端 未结 6 1974
故里飘歌
故里飘歌 2021-02-19 18:08

I know there has been a question asked on this topic, but none of the answers have helped me. I don\'t need help with implementing the code, I just need help sorting through the

6条回答
  •  南方客
    南方客 (楼主)
    2021-02-19 18:33

    You can write your recursive function to take 3 arguments: the first and second smallest values you've encountered so far, and the rest of the list, which you haven't inspected.

    Then, by comparing the first element of the list argument with the two smallest-so-far, you can choose which 2 of the 3 to pass as the arguments to the next recursion.

    You need to wrap this recursive function in a presentation function, which sets up and calls the recursive one, while handling cases like lists that have less than 2 elements.

    def recurse(min1, min2, list):
        if len(list)==0:
            return min2
        first, rest = list[0], list[1:]
        if first < min1:
            return recurse(first, min1, rest)
        if first < min2:
            return recurse(min1, first, rest)
        return recurse(min1, min2, rest)
    
    def second_smallest(list):
        if len(list) < 2:
            raise ValueError("too few elements to find second_smallest")
        a, b, rest = list[0], list[1], list[2:]
        if b < a:
            return recurse(b, a, rest)
        else:
            return recurse(a, b, rest)
    

    This kind of solution isn't particularly Pythonic -- it's more of a functional programming style.

    Finally, you can pass the arguments on the front of the list, and combine the two functions to get the kind of solution you're looking for:

    def second_smallest(list):
        if len(list) < 2:
            raise ValueError("too few elements to find second_smallest")
        a, b = list[0], list[1]
        a, b = min(a,b), max(a,b)
        if len(list) == 2:
            return b
        c, rest = list[2], list[3:]
        if c < a:
            return second_smallest([c,a]+rest)
        if c < b:
            return second_smallest([a,c]+rest)
        return second_smallest([a,b]+rest)
    

    Note that this function does some redundant work, because it can't know if it's being called first, or if it's calling itself recursively. Also, + creates a new list, so this code will likely take O(n^2) time for a list of size n.

提交回复
热议问题