我有以下数字列表:
numbers = numbers = [ 1, 3, 11, 12, 14, 15, 16, 3, 4, 6]
我想获取最长连续数字范围的开始和结束索引。连续范围是指不跳过的整数范围,即1,2,3,4,5 ...
这是我的方法:
def get_longest_consecutive_numbers(numbers):
# 1. Split the numbers list into sublists of consecutive numbers
split_list = []
j = 0
for i in range(1,len(numbers)-1):
if numbers[i]+1 is not numbers[i+1]:
split_list.append(numbers[j:i])
j = i
# 2. Find index of longest sublist (of consecutive numbers)
longest_sublist_index = max((len(l), i) for i, l in enumerate(split_list))[1]
# 3. Concatenate all sublists up to this index back together
rest = split_list[:longest_sublist_index]
concat_list = [j for i in rest for j in i]
# 4.
# Start Index: Length of concatenated list
# End Index: Start Index + Length of longest sublist in split_list
start_index = len(concat_list)
end_index = start_index + len(split_list[longest_sublist_index])
return start_index, end_index
如果我将函数应用于数字列表:
get_longest_consecutive_numbers(numbers)
我得到:
(3, 6)
这是正确的...但是...
我想知道是否还有一种更简单(更好)的方法?
答案 0 :(得分:2)
您还可以对其使用递归:
numbers = [1, 3, 11, 12, 14, 15, 16, 3, 4, 6]
def getMaxConsecutiveInd(index):
if numbers[index] + 1 == numbers[index + 1]:
# call the functions if values are cosecutive to check next value
return getMaxConsecutiveInd(index + 1)
# return last index for cosecutive numbers
return index
max_length, start_index, end_index = 0,0,0
i = 0
while i < len(numbers) - 1:
con_index = getMaxConsecutiveInd(i)
# if available max_length is less than new_max_length(con_index - i)
# then change start_index and end_index
if max_length < con_index - i:
max_length = con_index - i
start_index = i
end_index = con_index
# change value of i to latest con_index if i != con_index
if i == con_index:
i = i + 1
else:
i = con_index
print(start_index, end_index, max_length)
Output: (4,6,2)
numbers = [1, 2, 3, 4, 5, 6, 7, 11, 12, 14, 15, 16, 17, 18, 3, 4, 6]
Output: (0,6,6)
答案 1 :(得分:1)
如何使用2指针方法:
您将获得O(n)时间和O(1)额外空间。
答案 2 :(得分:1)
让我们玩得开心:
创建包含列表的范围
列表与列表的对称差异
计算以下两个数字之间的最大距离(为您提供最大长度)
获取起点和终点的索引
这是代码:
def longest_weird(numbers):
delta = list(set(range(max(numbers))).symmetric_difference(numbers))
start,end = 0,0
maxi = 0
for i,x in enumerate(delta[:-1]):
aux = max(maxi,delta[i+1]-x)
if aux != maxi:
start,end = (x+1,delta[i+1]-1)
maxi = aux
return numbers.index(start),numbers.index(end)
答案 3 :(得分:1)
numbers = [ 1, 3, 11, 12, 14, 15, 16, 3, 4, 6]
def longest(numbers):
max, count_ = 1, 1
start_idx, end_idx = 0, 0
for i in range(len(numbers)-1):
# if difference between number and his follower is 1,they are in sequence
if numbers[i+1]-numbers[i] ==1:
count_ = count_+1
else:
if count_ > max :
max = count_
end_idx = i
start_idx = i+1 - max
# Reset counter
count_ = 1
return (start_idx,end_idx,max)
print (longest(numbers))
输出:
(4, 6, 3) #start_idx, end_idx, len
答案 4 :(得分:1)
您可以使用numpy.diff
来计算列表中连续元素之间的差异,然后使用itertools.groupby
来收集差异等于1的元素。
import numpy as np
from itertools import groupby
from operator import itemgetter
def get_longest_consecutive_numbers(numbers):
idx = max(
(
list(map(itemgetter(0), g))
for i, g in groupby(enumerate(np.diff(numbers)==1), itemgetter(1))
if i
),
key=len
)
return (idx[0], idx[-1]+1)
print(get_longest_consecutive_numbers(numbers))
#(4,6)