3n + 1挑战非常受欢迎,可以找到here
我在下面的python中创建了一个解决方案,也在github
上创建了一个解决方案def solution(i, j):
count = toRtn = 1
for n in xrange(i, j+1):
count = 1
while n != 1:
if n % 2 == 0:
n = n/2
else:
n = (3 * n) + 1
count += 1
toRtn = max(toRtn, count)
return toRtn
print solution(100, 200)
print solution(201, 210)
我有几个问题:
可以而且应该将其重写为递归吗?那会提高效率吗?
如何计算此功能的复杂程度?
是否有针对这些挑战的Python在线评判?
答案 0 :(得分:3)
您可以定义递归方法来计算3n+1
def threen(n):
if n ==1:
return 1
if n%2 == 0:
n = n/2
else:
n = 3*n+1
return threen(n)+1
为避免计算两次相同的数字,您可以缓存值
cache = {}
def threen(n):
if n in cache:
return cache[n]
if n ==1:
return 1
orig = n
if n%2 == 0:
n = n/2
else:
n = 3*n+1
count = threen(n)+1
cache[orig] = count
return count
现在你可以在循环中使用它
def max_threen(i, j):
max3n = 0
for n in xrange(i, j+1):
max3n= max(threen(n), max3n)
print i, j, max3n
max_threen(100,201)
现在你可以将它与你的版本:)进行比较,它可能消耗大量内存,但对于某些范围可能更快,显然如果你缓存值,非递归方法会更快,但递归很有趣,更易读,但在任何情况下,迭代版本将更快与缓存(未测试)
cache = {}
def solution(i, j):
count = toRtn = 1
for n in xrange(i, j+1):
count = 1
orig = n
if n in cache:
count = cache[n]
else:
while n != 1:
if n % 2 == 0:
n = n/2
else:
n = (3 * n) + 1
count += 1
cache[orig] = count
toRtn = max(toRtn, count)
return toRtn
答案 1 :(得分:0)
n
的所有值。 (没有人发现没有返回的那个,但也没有人证明没有一个。)答案 2 :(得分:0)
1)严格来说,递归本身不能优化自身。递归不是关于优化,而是关于需要时的清晰度。但是,您可以使用带有memoization的递归来提高性能:http://en.wikipedia.org/wiki/Memoization
2)每个语句的复杂性的函数和的复杂性。因此,要计算整个复杂性,您应该为每一行构建一个包含两列的表:[调用次数],[复杂性]并对每行进行求和。我们来看看以下代码: def print_N_times(N):
print "------" #Line1
for i in range(0,N): #Line2
print "easy" #Line3
print "------" #Line4
------------------------------------------------------- | Line number | Number of times executed | Complexity | | Line 1 | 1 | 1 | | Line 2 | N+1 | 1 | | Line 3 | N | 1 | | Line 4 | 1 | 1 | -------------------------------------------------------
(这里1代替了常数的复杂性)
因此,通过将每列相乘并将它们相加:
1 * 1 +(N + 1)* 1 + N * 1 + 1 * 1 = 2 * N + 3 = O(N),因此该函数具有线性复杂度。
3)有很多评委,但是spoj.pl接受各种编程语言:
http://www.spoj.com/problems/PROBTRES/
编辑:在评论中正确地指出,对于3n + 1问题,您不知道[执行次数]列的每个值,或者该函数是否将完成。有关详细信息,请参阅: