【译】计算和重新排列

107 阅读3分钟

问题陈述。

Manju被赋予一项任务,即从一组排序的数字中找出给定数字的数量,然后将这些数字推到数组的前面,以方便拿起和计算。

讨论过的解决方法。

从这个编码问题中得到的关键收获。

For example:
If the numbers are 1, 1, 2, 2, 2, 2, 6 and you are given number 2 to count and push it to the front then, the final output would look like
Output: 2, 2, 2, 2, 1, 1, 6

你能在时间复杂度为O(logn),空间复杂度为O(1)的情况下做到吗? 只考虑寻找和计算数字

现在,暂时忘掉你所得到的时间复杂度,暂时想一想找到问题的解决方案的最基本方法。

让我们把这个问题分成两个子问题:
-1.找出给定数字的数量
2.

把给定的数字排列在起始位置。

将给定的数字排列在所有其他数字的开头。

让我们编写代码

天真的解决方案。

这个问题的 粗暴解决方法是使用 线性搜索 来计算数字的出现次数,然后将该数字重新排列在所有其他数字的前面。

让我们来看看这个方法的算法。

start function searchElementandSwapp(array, array_size, number){
     /* Get the count of the number and the index where it was first found */
     start for (index is 0 to index is less than array_size increment index by 1)
     /* Now swapp the numbers */
     start for (index is 0 to index is less than array_size and array[initialIndex] is equal to number increment  by 1)
end searchElementandSwapp

这个算法需要O(n)的时间来执行,并以O(1)的空间来完成操作。

这个算法对于大尺寸的数组来说肯定是失败的,而且对于大尺寸的数组来说效率也很低,那么我们应该怎么想才能进一步优化它?

你听说过二进制搜索算法 吗?

这个问题满足了所有可以使用二进制搜索的规则,因为数组是完全排序的,我们可以在 **O(logn)**的时间内找到我们想要的元素!

二进制搜索法。

让我们讨论一下首先找到在数组中出现的元素的算法。

start function searchElement(array, start_index, end_index, number)
       start if(end_index is less than 1)
       mid_index = start_index + (end_index - start_index) / 2
       start if(array[mid_index] is less than number)
       start else
end searchElement

现在,在搜索之后,我们需要计算一个给定的数字在数组中的出现次数,为此,我们可以将算法写为

start function countElement(array, array_size, number)
     getIndex = searchElement(array, 0, array_size - 1, number)
     /* if the element is not present */
     start if(getIndex is equal to -1)
     /* count left side */
     /* count right side */
     start while(rightCountIndex is less than the array_size and   array[rightCountIndex] is equal to number)
     print count 
     return initialIndex
end countElement

现在,我们有了initialIndex,所以我们可以很容易地用它来交换前面的数字**(如在天真的交换方法中所示,我们将使用同样的方法)**,轰!你已经在预期的时间内解决了问题。

现在,由于你已经知道了问题背后的算法 ,所以,你可以用你想要的编程语言编写你自己的函数式代码

分析一下。

  • 时间复杂度。O(logn),其中n是给定数组的大小,这是因为我们使用的是二进制搜索方法。
  • 空间复杂度。O(1), 因为我们没有使用任何额外的空间来存储这些元素。

继续学习,继续成长,也继续探索更多!

万事如意!

欲了解更多有趣和有价值的文章和技巧,请关注我的网站 媒介 链接


Count and Rearrange最初发表在Medium上的Javarevisited,在那里人们通过强调和回应这个故事来继续对话。