当前位置: 首页 > 知识库问答 >
问题:

不使用排序的最大三重积?

张丰
2023-03-14

我实现了最大的三重乘积算法,但我使用了排序,这使得我的时间复杂度为O(nlogn)。有没有办法在没有临时排序数组的情况下实现它?

问题:给定一个由n个整数组成的列表arr[0...(n-1)]。您必须计算一个列表输出[0...(n-1)],以便对于每个索引i(在0和n-1之间,包括在内),输出[i]等于arr[0... i]中三个最大元素的乘积(如果i

示例:

var arr_2 = [2, 4, 7, 1, 5, 3];
var expected_2 = [-1, -1, 56, 56, 140, 140];

我的解决方案:

function findMaxProduct(arr) {
  // Write your code here
  if(!arr || arr.length === 0)  return [];
  
  let helper = arr.slice();
  helper.sort((a,b)=>a-b);   // THIS IS THE SORT
  
  let ans = [];
  let prod = 1;
  for(let i=0; i<arr.length; i++) {
    if(i < 2) {
      prod *= arr[i];
      ans.push(-1);
    }
    else {
      if(i === 3) {
        prod *= arr[i];
        ans.push(prod);
      } else if(arr[i] < helper[0]) {
        ans.push(prod);
      } else {
        const min = helper.shift();
        prod /= min;
        prod *= arr[i];
        ans.push(prod);
      }
    }
  }
  
  return ans;
}

谢啦

共有3个答案

董胡媚
2023-03-14

我认为有一种更快、更有效的方法可以做到这一点。这是一个类似于@Q2Learn的思维过程,使用Python;更快:

def findMaxProduct(arr):
 
  #create a copy of arr
    
  solution = arr.copy()
  # make first 2 elements -1
  for i in range(0,2):
    solution[i] = -1
    
#for each item in copy starting from index 2, multiply  item from 2 indices b'4 (notice how each index of arr being multiplied is reduced by 2, 1 and then 0, to accommodate each move)
  
  for i in range(2, len(arr)):
    solution[i] = arr[i-2] * arr[i-1] * arr[i]
  return solution

check = findMaxProduct(arr)
print(check)
汪翰墨
2023-03-14

您可以创建一个包含三个当前最大整数的数组,并在通过原始数组时更新该数组。这就是为什么您总是有三个当前最大的数字,并且您将能够以O(n)的时间复杂性来解决这个问题。

翟曦之
2023-03-14

您不需要对其进行排序。您只需在每个索引处维护一个由最大的三个元素组成的数组。

对于前三个元素很简单,您只需将它们的乘积分配给结果中的第三个元素。

对于接下来的元素,将当前元素添加到三个最大的元素数组中,并对其进行排序,从1到3(最大的三个)取元素,然后在结果数组中指定该索引处元素的乘积。然后用最大的三个元素更新三元素数组。

  • 复杂性:

三元素数组的排序和切片应该是O(1),因为每次atmost都有4个元素在数组中。

总体复杂度为O(n)。

您可以按以下方式执行

function findMaxProduct(arr) {
  if(!arr)  return [];
  if (arr.length < 3) return arr.slice().fill(-1)
  let t = arr.slice(0,3)
  let ans = arr.slice().fill(-1,0,2) //fill first two with -1
  ans[2] = t[0]*t[1]*t[2];
  for(let i=3; i<arr.length; i++) {
    t.push(arr[i]);
    t = t.sort().slice(1,4);
    ans[i] = t[0]*t[1]*t[2];
  }
  return ans;
}
 类似资料:
  • 我只是想看看我是否理解教授和在线资源所说的话。 对于heapSort算法,第一个元素的索引从0开始。 对于最大堆,如果子堆大于父堆,则percolate down应将最大子堆与其父堆交换,例如(这是用于赋值,因此我尝试发布尽可能少的代码): 所以最后,最大元素应该在索引0处。 如果这是正确的,我不理解的是heapSort实现: 最大堆中的渗滤层不应该将最大的元素放在索引0处吗?在这种情况下,为什么

  • 我注意到一件非常奇怪的事情。 读完这节课后,我在C中实现了一些堆排序代码。 代码如下。 奇怪的是,对我来说,构建min堆-提取min(或在构建min堆后在根目录下执行min-heapify)应该按升序进行。然而,在执行此代码并打印出结果向量后,我得到: 在试图弄清楚发生了什么的时候,我改变了 到 最终选择较大(或最大)的父节点和子节点,得到的向量为: 我是否做错了什么,或者我对堆/堆排序的理解不清

  • 输出: 我在哈希表中寻找k个最大的对(它们的数目),而输出中的那些实际上是正确的。我的问题是,为什么最后两个交换了?

  • 对于堆排序,如果我们想按升序对数组排序,那么应该在最大堆还是最小堆中转换堆?

  • 我在[17,98,89,42,67,54,89,25,38]中有一个数字列表,从左到右插入到一个空堆中。生成的堆是什么?

  • 我对min()和max()中关键参数的行为有点迷惑不解 假设我有以下列表: 我希望max值高于20,所以我做了:。结果是25,应该是50。 我希望max值低于20,所以我做了:。结果是10,应该是15。 min()也是如此。如果我希望最小值大于20(),则给出的值是10,而不是25。 谁能帮忙解释一下吗?我想更好地理解,以避免在处理不同条件时出现错误。