【问题标题】:How to find the Kth largest difference in int[]?如何找到 int[] 中的第 K 个最大差异?
【发布时间】:2019-02-05 09:27:12
【问题描述】:

我有一个算法问题。

例如,有一个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)

有更好的解决方案吗?

【问题讨论】:

  • 您可能希望为给定示例添加预期结果。
  • 我对@9​​87654331@的理解正确吗?
  • @dehasi No. ex: 对于[8 ,4 ,1 ],第二大区别是8 - 4 = 4 不是4 - 1 = 3
  • 要找到两个元素之间的第 k 个最大元素,您需要始终迭代 n^2。不要认为有改进的余地
  • 这里提供了一个 O(n*log(n)*log(n)) 解决方案来找到第 k 个最小差异geeksforgeeks.org/…。应该很容易适应第 k 个最大的。

标签: java arrays algorithm time


【解决方案1】:

它可以复杂地完成O( N * logN + N * logValMax )。首先让我们对数组进行排序。之后我们可以构建一个函数countSmallerDiffs( x ),它计算数组中有多少小于或等于x的差异,这个函数使用两个指针具有复杂度O(N)。之后,我们可以在minVal-maxVal 范围内对结果进行二分搜索。我们需要找到满足countSmallerDiffs( p ) <= k < countSmallerDiffs( p + 1 )p。答案是p

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

【讨论】:

    【解决方案2】:

    在伪代码方面,它可以这样:

    您可以对当前数组进行降序排序,然后像这样开始计算:

    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)。

    您可以将数组替换为最方便的集合,并将其展开为迭代解决方案。

    感谢指正!

    【讨论】:

    • 所以这不会按照您的要求返回 j,但是您可以将数组元素替换为保留原始索引的元组。
    【解决方案3】:

    示例:

    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)]
    

    您可以对结果数组进行排序,然后得到第 k 个差异。

    【讨论】:

      【解决方案4】:

      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

      【讨论】:

      • 那是在寻找最大的差异,这不是被问到的。
      【解决方案5】:

      您可以运行 2 个单独的方法来查找相应数组的最大值和最小值,然后找出差异。

      您可以使用创建一个新数组的方法来查找每个值的差异,然后找到该数组的最大值并输出。

      然后使用 Array sort() 方法对数组进行重新排序,并在 index+1 调用时打印出最大差值

      【讨论】:

      • 这仅适用于 K=1。 K=2 第二大呢?
      • 编辑现在可以工作:添加了 Array sort() 方法,该方法可以通过按从最大到最小的顺序组织数组来使其工作,然后用户可以使用 (index) 调用第 K 个最大差异+1) 价值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-09
      • 2021-11-01
      • 2016-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      相关资源
      最近更新 更多