我需要减少代码的时间复杂度,到目前为止,我尝试对其进行预排序,并使用二进制搜索来查找所需元素的索引,并使用索引来查找键号之前有多少个元素,但是我可以无法通过,因为我的代码很慢。我还有其他方法可以使此代码更快吗?
重要细节:
示例:
假设我有一个包含15个元素的数组,并且要执行5个查询。
数组:1002 19 3 8 22 123 14 5234 123 657 41 829 34 2314 15
查询:100 1000 78 3 1
输出:8 12 8 1 0
我尝试对其进行预排序并使用二进制搜索,但仍然无法通过0,1s的时间限制。
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<div class="container">
<div class="row">
<div class="g-container-upper">
<div id="g-container" >
<div id="left-canvas" class="row justify-content-md-center">
<svg id="left-svg">
<g>
<line id="svg-left-line" x1="5" x2="5" y1="0"></line>
</g>
<g></g>
</svg>
<canvas id="g-canvas" style="border:1px solid #000000;"></canvas>
</div>
</div>
<div class="row">
<div id="bottom-canvas">
<svg id="bottom-svg" class="row justify-content-md-center">
<g>
<line id="svg-bottom-line" x1="0" y1="5" y2="5"></line>
</g>
</svg>
</div>
</div>
</div>
</div>
</div>
答案 0 :(得分:1)
通常,您的方法是正确的,应该提供平均时间NlogN + MlogN
,其中N是数组大小,M是查询数。
但是qsort
的实现还不够好-它总是选择正确的元素作为数据透视表,并且对于某些数组(已排序的数组或包含重复的元素)给出二次排序时间!
如果您不能使用标准库中的排序例程,只需更改实现-在随机索引处获取数据点或使用“ median of three”方法
P.S。还可以考虑用Hoare的方法代替使用过的Lomuto的分区方法(它不是那么简单,但是更快)
答案 1 :(得分:0)
首先,您能告诉我们您为给定的迭代列表固定了100k元素数组时,当前选择的执行时间是多少?这将使我们了解您离极限有多远。
第二,执行时间不仅取决于复杂度,还取决于每个循环的执行时间。这就是为什么您可以拥有两种具有不同复杂度的算法,但是具有较高复杂度的一种算法比另一种算法运行速度更快的原因仅在于它在足够少的元素上运行。 这样说,对于您来说,复杂性肯定是有作用的。但是,每个循环的运行时间很重要,这取决于实现方式。因此,我可以提出以下建议:
mid = left + (right-left)/2;
可以简化为mid = (left + right) >> 1;
。这将已经提高了代码速度。 (我已经编辑了此部分,将右移更改为1)0
进行测试,您的代码将更快。
1 - 2 - 3 - 7
- 5 - 6
- 5
2 - 4
- 6
此后,只需要沿着树行进并比较每个数字的长度和值即可。
不过只是个主意!