gpt4 book ai didi

algorithm - "divide and conquer"算法分配

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:50:17 25 4
gpt4 key购买 nike

现在我有 N 个不同的整数,我需要找到一个区间,它的值在 O(NlogN) 时间内位于区间端点之间的数字最多。我称它为“分而治之”问题,因为它属于我期末考试的“分而治之”类别。我已经考虑了 2 周并做了很多实验,但没有一个是正确的(与蛮力算法相比)。有人可以帮助我吗?

例子:

8,1,3,4,7。答案是 1-7。

2,6,5,4,9,8。答案是 2-9 或 2-8。

我认为“间隔”这个词没有表达我的意思。我的意思是找到数组的一个子序列,该子序列的值在子序列的端点之间。例如 1:“1,3,4,7”有两个数字 (3,4),例如 2:“2,6,5,4,9”和“2,6,5,4,9” ,8"有三个数字 (6,5,4)。

这是我的代码(O(n^2))。 @Vaughn Cato 我用它来与您的代码进行比较。

#! /usr/bin/env python
#coding=utf-8
import itertools
def n2(numbers):
a = [0]*len(numbers)
ans = -1
l = 0
r = 0
for j in range(1,len(numbers)):
t = 0
for i in range(j-1,-1,-1):
if numbers[i]<numbers[j]:
x = t - a[i]
if x>ans:
ans = x
l = i
r = j
t += 1
else:
a[i] += 1
return (numbers[l],numbers[r],ans)

def countBetween(numbers,left,right):
cnt = 0
for i in range(left+1,right):
if numbers[left]<numbers[i]<numbers[right]:
cnt += 1
return cnt

for numbers in itertools.permutations(range(5)):
ans1=n2(numbers)
ans2=longestInterval(numbers)
if(ans1[2]!=ans2[2]):
print ans1,ans2,numbers

最佳答案

注意:这实际上不起作用,但它可能会给您一些想法。

这样想:

  • X是数字数组。
  • s是子序列开始的索引。
  • e是子序列结尾的索引。

如果您选择任意分区索引 p ,那么最长的子序列要么穿过这个分区,要么落在那个分区的左边或右边。如果最长的子序列穿过这个分区,那么s < p <= e .寻找s , 找到 s 之间数字最多的索引和 p大于 X[s]。要查找“e”,请找到 p 之间数字最多的索引和 e小于 X[e]。

你可以递归地检查左边和右边,看看你是否能找到更长的子序列。

如果您有 X 的索引,则可以在线性时间内找到哪个索引在右边的数字最大或在左边的数字最少。按值排序:

要找到起始索引,请从您排序的索引列表的第一个索引开始,并说它是迄今为止最好的。如果下一个索引大于迄今为止最好的索引,那么任何 future 的索引都需要比我们当前的最佳索引更靠左才能成为新的最佳索引,因此我们从最佳索引中减去一个(但请记住最佳索引是什么真的是)。如果下一个索引在我们最佳索引的左侧,则使其成为最佳索引。对每个索引按顺序重复此过程。

您可以执行类似的过程来找到右侧末端的最佳索引。

剩下的唯一技巧是为我们正在处理的任何范围维护索引的排序列表。这可以通过最初对整个数字集进行排序并找到它们的索引来完成,然后在递归的每个级别,我们可以在线性时间内将排序后的索引拆分为两个子列表。

这是这个想法的 python 实现:

# Find the index from the given indices that has the most numbers to the
# right of it which are greater in value. The indices are sorted by
# the value of the numbers at that index. We don't even need to know
# what the numbers are.
def longestLowerSequence(indices):
best_index=indices[0]
target_index=best_index
for i in range(0,len(indices)):
if indices[i]<target_index:
best_index=indices[i]
target_index=best_index
else:
target_index-=1
return best_index

# Find the index from the given indices that has the most numbers to the
# left of it which are less in value.
def longestUpperSequence(indices):
n=len(indices)
best_index=indices[n-1]
target_index=best_index
for i in range(0,n):
if indices[n-1-i]>target_index:
best_index=indices[n-1-i]
target_index=best_index
else:
target_index+=1
return best_index

# Return the pair of indices which has the most values between it.
def longestRangeFromSortedIndices(numbers,indices,begin,end):
assert end>begin
if end-begin<=2:
return (indices[begin],indices[end-1])
assert type(indices) is list
partition=(begin+end)/2
left_indices=filter(lambda index: index<partition,indices)
right_indices=filter(lambda index: index>=partition,indices)
assert len(left_indices)>0
assert len(right_indices)>0
left=longestLowerSequence(left_indices)
right=longestUpperSequence(right_indices)
left_range=longestRangeFromSortedIndices(numbers,indices,begin,partition)
right_range=longestRangeFromSortedIndices(numbers,indices,partition,end)
best_size=countBetween(numbers,left,right)
best_range=(left,right)
left_size=countBetween(numbers,left_range[0],left_range[1])
right_size=countBetween(numbers,right_range[0],right_range[1])
if left_size>best_size:
best_size=left_size
best_range=left_range
if right_size>best_size:
best_size=right_size
best_range=right_range
return best_range

def sortedIndices(numbers):
return sorted(range(len(numbers)),key=lambda i: numbers[i])

def longestInterval(numbers):
indices=sortedIndices(numbers)
longest_range=longestRangeFromSortedIndices(numbers,indices,0,len(numbers))
return (numbers[longest_range[0]],numbers[longest_range[1]])

关于algorithm - "divide and conquer"算法分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14580442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com