다음은 CPU를 희생하면서 일정한 메모리로 실행되는 답변입니다. 이것은 원래 질문의 맥락에서 좋은 대답이 아닙니다 (예 : 인터뷰 중 답변). 그러나 인터뷰 시간이 24 시간이면 그리 나쁘지 않습니다. ;)
아이디어는 내가 유효한 답인 n을 가지고 있다면, 순서의 다음은 2의 거듭 제곱을 5의 거듭 제곱으로 나눈 값이 될 것입니다. 그렇지 않으면 n의 5의 거듭 제곱은 2의 힘. 그것이 균등하게 나눠 졌다면. (... 또는 제수는 1 일 수 있습니다.)이 경우 2 또는 5를 곱하면됩니다.
예를 들어, 625에서 640으로 가려면 5 ** 4/2 ** 7을 곱하십시오. 또는 더 일반적으로, 2 ** m * 5 ** n
일부 m에 대해 n의 값을 곱하면 n은 양수이고 하나는 음수 또는 0이며 승수는 숫자를 균등하게 나눕니다.
이제 까다로운 부분은 승수를 찾는 것입니다. 그러나 우리는 a) 제수가 숫자를 균등하게 나눠야한다. b) 승수는 1보다 커야한다 (숫자는 계속 증가한다), 그리고 c) 최저 승수를 1보다 크게 선택한 경우 (즉, 1 <f <다른 모든 f ) 다음 단계가 보장됩니다. 그 이후의 단계는 가장 낮은 단계입니다.
불쾌한 부분은 m, n의 값을 찾는 것입니다. 포기할 수있는 2 또는 5가 너무 많기 때문에 log (n) 가능성 만 있지만 반올림을 처리하는 부주의 한 방법으로 -1에서 +1의 요소를 추가해야했습니다. 따라서 우리는 각 단계마다 O (log (n))를 반복해야합니다. 전체적으로 O (n log (n))입니다.
좋은 소식은 값을 가져와 다음 값을 찾기 때문에 시퀀스의 어느 곳에서나 시작할 수 있다는 것입니다. 따라서 10 억 이후에 다음을 원한다면 2/5 또는 5/2를 반복하고 1보다 큰 가장 작은 승수를 선택하면 찾을 수 있습니다.
(파이썬)
MAX = 30
F = - math.log(2) / math.log(5)
def val(i, j):
return 2 ** i * 5 ** j
def best(i, j):
f = 100
m = 0
n = 0
max_i = (int)(math.log(val(i, j)) / math.log(2) + 1) if i + j else 1
#print((val(i, j), max_i, x))
for mm in range(-i, max_i + 1):
for rr in {-1, 0, 1}:
nn = (int)(mm * F + rr)
if nn < -j: continue
ff = val(mm, nn)
#print(' ' + str((ff, mm, nn, rr)))
if ff > 1 and ff < f:
f = ff
m = mm
n = nn
return m, n
def detSeq():
i = 0
j = 0
got = [val(i, j)]
while len(got) < MAX:
m, n = best(i, j)
i += m
j += n
got.append(val(i, j))
#print('* ' + str((val(i, j), m, n)))
#print('- ' + str((v, i, j)))
return got
정렬 된 목록 솔루션으로 생성 된 첫 번째 10,000에 대해 생성하는 처음 10,000 개의 숫자를 확인했으며 적어도 그 정도까지 작동합니다.
BTW 다음 조 1 조 뒤에 1,024,000,000,000 인 것으로 보입니다.
...
흠. best()
점진적으로 확장되는 조회 테이블로 처리하여 O (n) 성능-값당 O (1) (!) 및 O (log n) 메모리 사용량을 얻을 수 있습니다. 지금은 매번 반복하여 메모리를 절약하지만 많은 중복 계산을 수행하고 있습니다. 중간 값과 최소값 목록을 유지하면 중복 작업을 피하고 속도를 크게 높일 수 있습니다. 그러나 중간 값 목록은 n에 따라 증가하므로 O (log n) 메모리입니다.