如何找到int []的Kth最大差?

时间:2018-08-30 12:20:55

标签: java arrays algorithm time

我有一个算法问题。

例如,有一个int[]数组,例如[1,5,4,3,7,2]

我想在此数组中找到第k个最大的差异,例如:

array[i] - array[j] = kth largest difference

(索引i必须小于j,而array[i]必须大于array[j])。

输出返回此问题中的j

我当前的想法:

  • 我可以构建一个int[][]来将所有差异存储在数组中。
  • 然后对它们进行排序,找出第k个最大差异。

但是时间复杂度为O(n^2)

有更好的解决方案吗?

5 个答案:

答案 0 :(得分:1)

Python示例

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 )

希望这对您有所帮助!祝你好运!