因此,这是可能著名的codility平台的另一种方法,即关于青蛙过河的任务。很抱歉,如果这个问题的提问方式不好,这是我在这里的第一篇文章。
目标是找到青蛙跳到河对岸的最早时间。 例如,给定X = 5且数组A使得:
A[0] = 1
A[1] = 3
A[2] = 1
A[3] = 4
A[4] = 2
A[5] = 3
A[6] = 5
A[7] = 4
该函数应返回6。
示例测试:(5,[1、3、1、4、2、3、5、4])
全部任务内容: https://app.codility.com/programmers/lessons/4-counting_elements/frog_river_one/
这是我第一个显而易见的方法:
def solution(X, A):
lista = list(range(1, X + 1))
if X < 1 or len(A) < 1:
return -1
found = -1
for element in lista:
if element in A:
if A.index(element) > found:
found = A.index(element)
else: return -1
return found
X = 5
A = [1,2,4,5,3]
solution(X,A)
此解决方案是100%正确的,在性能测试中为0%。
所以我认为更少的行数和列表理解将获得更好的分数:
def solution(X, A):
if X < 1 or len(A) < 1:
return -1
try:
found = max([ A.index(element) for element in range(1, X + 1) ])
except ValueError:
return -1
return found
X = 5
A = [1,2,4,5,3]
solution(X,A)
这也可以并且具有0%的性能,但是无论如何它都更快。
我还发现了deanalvero(https://github.com/deanalvero/codility/blob/master/python/lesson02/FrogRiverOne.py)的解决方案:
def solution(X, A):
# write your code in Python 2.6
frog, leaves = 0, [False] * (X)
for minute, leaf in enumerate(A):
if leaf <= X:
leaves[leaf - 1] = True
while leaves[frog]:
frog += 1
if frog == X: return minute
return -1
此解决方案通过了100%的正确性和性能测试。
之所以出现这个问题,可能是因为我不太了解这次的复杂性。请告诉我最后一个解决方案比第二个解决方案更好吗?它在for循环中有一个while循环!它应该很慢,但不是。
答案 0 :(得分:2)
在这里,您将获得100%的正确性和性能。
def solution(X, A):
i = 0
dict_temp = {}
while i < len(A):
dict_temp[A[i]] = i
if len(dict_temp) == X:
return i
i += 1
return -1
答案 1 :(得分:1)
答案已经被告知,但是我将添加一个可选的解决方案,我认为它可以帮助您理解:
def save_frog(x, arr):
# creating the steps the frog should make
steps = set([i for i in range(1, x + 1)])
# creating the steps the frog already did
froggy_steps = set()
for index, leaf in enumerate(arr):
froggy_steps.add(leaf)
if froggy_steps == steps:
return index
return -1
答案 2 :(得分:1)
这是我如何解决它并获得0个性能的方法:
def solution(X, A):
# write your code in Python 3.6
if X not in A: return -1
else: return [i for i in range(len(A)) if(A[i]==X)][0]
我只用了两行就得到了这种表现!!
答案 3 :(得分:0)
嵌套循环的数量并不能直接告诉您时间的复杂性。假设 n 为输入数组的长度。 while循环内部需要平均值 O(1)时间,尽管最坏情况下的时间复杂度是 O(n)。快速解决方案使用布尔数组 leaves ,其中在每个索引中,如果有叶子,则其值为 true ,否则为 false 。在整个算法中,while循环的内部不超过 n 次。外部for循环也仅执行 n 次。这意味着算法的时间复杂度为 O(n)。
答案 4 :(得分:0)
关键是两个初始解决方案都是二次方。它们涉及对父元素的每个的O(n)内部扫描(导致O(n ** 2))。
快速解决方案最初似乎遭受同样的命运,因为显而易见,它包含一个循环。但是内部的while循环不会不会完全扫描每个“叶子”。看一下“青蛙”的初始化位置,您会注意到while循环有效地为每个叶子保留了它的终止位置。
答案 5 :(得分:0)
这是我考虑数字级数总和的 100% 解决方案。
def solution(X, A):
covered = [False] * (X+1)
n = len(A)
Sx = ((1+X)*X)/2 # sum of the numeric progression
for i in range(n):
if(not covered[A[i]]):
Sx -= A[i]
covered[A[i]] = True
if (Sx==0):
return i
return -1
答案 6 :(得分:0)
@sphoenix 的优化方案,不需要比较两个set
,不太好。
def solution(X, A):
found = set()
for pos, i in enumerate(A, 0):
if i <= X:
found.add(i)
if len(found) == X:
return pos
return -1
还有一种更优化的二进制数组解决方案
def solution(X, A):
steps, leaves = X, [False] * X
for minute, leaf in enumerate(A, 0):
if not leaves[leaf - 1]:
leaves[leaf - 1] = True
steps -= 1
if 0 == steps:
return minute
return -1
最后一个更好,资源更少。与二进制列表(内存和 CPU)相比,set 消耗更多资源。
答案 7 :(得分:0)
def solution(X, A):
# if there are not enough items in the list
if X > len(A):
return -1
# else check all items
else:
d = {}
for i, leaf in enumerate(A):
d[leaf] = i
if len(d) == X:
return i
# if all else fails
return -1