我有一个算法问题。
例如,有一个int[]
数组,例如[1,5,4,3,7,2]
。
我想在此数组中找到第k个最大的差异,例如:
array[i] - array[j] = kth largest difference
(索引i必须小于j
,而array[i]
必须大于array[j]
)。
输出返回此问题中的j
。
我当前的想法:
int[][]
来将所有差异存储在数组中。 但是时间复杂度为O(n^2)
。
有更好的解决方案吗?
答案 0 :(得分:1)
results = []
a = [1,5,4,3,7,2]
a_new = [(1,0), (5,1), (4,2), (3,3), (7,4), (2,5)] #(5,1) -> 5:value and 1:index
sort a_new by value # e.g. mergesort O(nlogn)
start_index = 0
end_index = len(a_new) - 1
i = -1
j = -1
diff = 0
while true: # sequential search
if(a_new[start_index][1] < a_new[end_index][1]): #compare i and j
tmp_diff = a_new[end_index][0] - a_new[start_index][0]
i = start_index
j = end_index
diff = tmp_diff
results.append((I,j,diff)) #add a tuple in results_list
end_index -= 1
else: # a_new[start_index][1] > a_new[end_index][1]
start_index += 1
if start_index == end_index: break
sort results by diff and return results[k-1]
我希望能有所帮助。我无法检查输入错误。
我的想法是:最大差是-> max_possible_element_value-min_element_value
答案 1 :(得分:1)
您可以运行2个单独的方法,分别找到对应数组的最大值和最小值,然后求出差值。
OR
您可以使用创建新数组的方法来查找每个单个值的差,然后查找该数组的最大值并将其输出。
然后使用Array sort()方法对数组重新排序并打印出由index + 1调用时的最大差值。
答案 2 :(得分:1)
在伪代码方面,它可能是这样的:
您可以对当前数组降序排序,然后像这样开始计算:
diffList = {}
calculate(array,k) :
if (k<=0) OR (array.length < 2) OR (k > 2^(array.length-1))
return nothing // whatever behavior you want (exception or null Integer whatever suits you)
else
return kthLargest(k, 0 , array.length-1, array)
end if
kthLargest(count, upperBound, lowerBound, array) :
if count = 0
if upperBound != lowerBound
return max(array[upperBound]-array[lowerBound], max(sortDesc(diffList)))
else
return max(sort(diffList))
end if
else if upperBound = lowerBound
sortDesc(diffList)
return diffList[count]
else
topDiff = array[upperBound]-array[upperBound+1]
botDiff = array[lowerBound-1]-array[lowerbound]
if(topDiff > botDiff)
add botDiff to diffList
return kthLargest(count-1,upperBound,lowerBound-1,array)
else
add topDiff to diffList
return kthLargest(count-1,upperBound+1,lowerBound,array)
end if
end if
调用calculate(array,k)就可以了。
这基本上会跟踪“丢弃的堆”差异,同时迭代和缩小边界以使最终最大差值始终是当前边界的差或该丢弃堆中潜在的更好价值。
这两种排序方式(为简洁起见均应省略)都应设为O(n log n)。
您可以将数组替换为最方便的集合,并将其解封装为迭代解决方案。
更正!
答案 3 :(得分:1)
results = []
a_new = [(1,0), (2,5), (3,3), (4,2), (5,1), (7,4)]
start_index = 0
end_index = len(a_new) - 1
i = -1
j = -1
diff = 0
while True:
if(a_new[start_index][1] < a_new[end_index][1]):
i = a_new[start_index][1]
j = a_new[end_index][1]
diff = a_new[end_index][0] - a_new[start_index][0]
results.append((i, j, diff))
end_index -= 1
else:
start_index -= -1
if start_index == end_index: break
print(results)
[(0, 4, 6), (0, 1, 4), (0, 2, 3), (0, 3, 2), (0, 5, 1)]
您可以对结果数组进行排序,然后得到kth diff。
答案 4 :(得分:0)
这可以很复杂地完成O( N * logN + N * logValMax )
。首先让我们对数组进行排序。之后,我们可以构建一个函数countSmallerDiffs( x )
,该函数计算数组中有多少个小于或等于x的差,该函数使用两个指针具有O(N)复杂度。之后,我们可以对范围minVal-maxVal
中的结果进行二进制搜索。我们需要找到满足p
的{{1}}。答案将是countSmallerDiffs( p ) <= k < countSmallerDiffs( p + 1 )
。
希望这对您有所帮助!祝你好运!