在寻求学习算法设计的过程中,我开始练习问题,而这些特殊问题使我难以找到有效的解决方案。
给定一个整数数组A,求j的最大值-i服从 A [i] <= A [j]的约束。 A:[3 5 4 2]输出:2对 (3,4)
def maxIndex(arr):
max_val = float("-inf")
for i in range(0,len(arr)):
for j in range(i + 1 , len(arr)):
#print(arr[i],arr[j])
if arr[i] <= arr[j]:
diff_i = j - i
if diff_i > max_val:
max_val = diff_i
return max_val
A = [3, 5, 4, 2]
print("Result :",maxIndex(A))
我上面的幼稚方法可以工作,但时间复杂度为O(n ^ 2),空间复杂度为O(1)。
这里的值和索引都很重要。如果我将列表排序不正确并将索引存储在字典中,我仍然必须使用嵌套的for循环来检查j - 1
约束。 / p>
如何改善时间复杂度?
答案 0 :(得分:0)
您可以创建两个辅助数组,以便最小数组在索引i处存储最小值,直到索引i,类似地,最大数组包含直到索引i的最大数组值(反向遍历) 您可以在这里https://www.geeksforgeeks.org/given-an-array-arr-find-the-maximum-j-i-such-that-arrj-arri/
找到答案答案 1 :(得分:0)
对于给定的问题,我可能会想到一个可能的解决方案,就是从给定的列表创建一个成对的列表,该列表保留列表索引以及列表值,即(A的列表 i ,i)列表中的所有元素。
您可以按升序对给定的成对列表进行排序,并从左到右进行迭代。我们维护一个变量,该变量表示到目前为止在迭代min_index
中遇到的最小索引。现在,在每个步骤 i 中,我们将答案更新为 ans = max(ans,index i -min_index)iff index i > min_index 以及我们的min_index以及我们的min_index
为 min_index = min(index i ,min_index)由于我们的列表已排序,因此可以确保 A [i]> = A [min_index]
由于我们需要首先对数组进行排序,所以该解决方案的总体复杂度为O(nlog(n))
答案 2 :(得分:0)
如上所述,is an O(n) solution是最有效的。我将在O(n log n)中添加另一种解决方法:
我们可以考虑这个问题,因为对于每个索引i,知道最远的索引j> i,其中a [i] <= a [j]。如果有了这个,我们只需要评估索引的差异并在其上保持最大值。那么,如何计算这些信息?
请注意,对于每个元素,我们需要在集合中搜索所有较低的值。搜索是O(log n),虽然我们可以进行更多的迭代,但是当我们稍后从集合中删除它时,我们只对每个元素进行了一次迭代,因此总体复杂度为O(n log n)。
答案 3 :(得分:0)
有一种方法使用O(nlogn)时间(虽然我感觉应该存在线性算法)。
列出min-candidates
遍历源列表。
如果当前项目小于当前最小值,则将其索引添加到min-candidates
。因此,相应的值将按降序排序。
如果当前项目大于当前最小值,请使用二进制搜索在min-candidates
中搜索第一少的项目。找到索引差异并与当前最佳结果进行比较。
答案 4 :(得分:0)
这可以在O(nlogn)时间和O(n)空间中解决。
min_index = list.length + 1
max = 0
max_tuple = []
for tuple t in list:
min_index = minimum( t.index, min_index )
if ( t.index != min_index )
if ( t.index - min_index >= max )
max = t.index - min_index
max_tuple = [min_index, t.index]
换句话说,您跟踪最小索引,并且由于列表已排序,因此当您按递增值顺序浏览列表时,您将在最小索引和当前索引之间得到一个需要最大化的差异。