简体   繁体   English

Python 以给定的索引跳转或更少的方式递归地跳转列表,同时避免零

[英]Python recursively jumping through a list by a given index jump or less while avoiding zeros

I am trying to write a function that has only one argument, a list of positive integers.我正在尝试编写一个只有一个参数的 function,一个正整数列表。

It has to be recursive and find whether you can get from the start to the end while avoiding landing on 0s.它必须是递归的,并找到是否可以从头到尾同时避免落在 0 上。 It has to start at first value list[0] but you can jump by either the full amount or less.它必须从第一个值list[0]开始,但您可以跳转全部或更少。

For example例如

list1 = [3,1,2,0,4,0,1]
list2 = [3,2,1,0,2,0,2]

List 1 should return True as you can jump from 3 to 2 to 4 to 1.清单 1 应该返回True ,因为您可以从 3 跳到 2 再到 4 再到 1。

List 2 should return False as it does not matter how you jump, you will land at the first 0.列表 2 应该返回False ,因为无论你如何跳跃,你都会在第一个 0 处着陆。

Here is my attempt so far:到目前为止,这是我的尝试:

def check_level(level):
    jump = level[0]
    if level[-1] == 0:
        return False
    elif jump == 0:
        return False
    
    elif jump == 0:
        return False
    
    elif len(level) > 1:
        if level[jump] > len(level):
            return True

        elif level[-1] == 0:
            return False
        
        elif level[0] != 0:
            if level[jump] == 0:
                level[0] -= 1
                return check_level(level)
            else:
                jump_index = level.index(level[jump])
                new_level = level[jump_index:]
                return check_level(new_level)

    else:
        return True

It does not work with all examples and with others it comes up with an error:它不适用于所有示例,而与其他示例一起出现错误:

if level[jump] > len(level):
TypeError: '>' not supported between instances of 'list' and 'int'```

I am out of ideas on how to approach this and whether my approach is failed from the start... I hate recursion, hence I need to practice it.

The general logic is:大体逻辑是:

"If you can jump to a True position, the current position is also True" “如果能跳到一个True position,当前position也是True”

Implemented like this:像这样实现:

def checklevel(lst):
    if not lst:
        # no list is True (we are done)
        return True  
    return any( checklevel(lst[i:]) for i in range(1,lst[0]+1))

list1 = [3,1,2,0,4,0,1]
list2 = [3,2,1,0,2,0,2]

assert checklevel(list1)
assert not checklevel(list2)

Note that this is a terrible solution for large lists, you should try a iterative dp-table in that case.请注意,这对于大型列表来说是一个糟糕的解决方案,在这种情况下您应该尝试迭代 dp-table。

After advancing by a number of positions, you simply have to recurse with the rest of the list.在前进了一些位置之后,您只需递归列表的 rest。 Do it for distances from 1 to the value of the first element and you're done:对从 1 到第一个元素的值的距离执行此操作,您就完成了:

def jumpable(A):
    if not A: return True # reaching end wins
    return any(jumpable(A[i+1:]) for i in range(A[0])) # try all distances

ouput:输出:

print(jumpable([3,1,2,0,4,0,1])) # True
print(jumpable([3,2,1,0,2,0,2])) # False

To avoid creating memory wasting temporary lists you can pass an index down (instead of a sublist) and use it as the starting point for the next level of recursion:为避免创建 memory 浪费临时列表,您可以向下传递索引(而不是子列表)并将其用作下一级递归的起点:

def jumpable(A,i=0):
    if i>=len(A) : return True # reaching end 
    return any(jumpable(A,i+j+1) for j in range(A[i])) # try all distances

With a default value for i=0, you function still has only one parameter when called from the outside. i=0 的默认值,你 function 从外部调用时仍然只有一个参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM