【发布时间】:2021-12-06 15:54:25
【问题描述】:
我正在尝试编写一个程序,其输入是一个整数数组及其大小。此代码必须删除小于左侧元素的元素。我们希望找到重复此操作以无法删除更多元素的次数。这是我的代码,它可以工作,但我希望它更快。
你有什么想法可以让这段代码更快,或者其他比这更快的方法吗?
例如,给定数组 [10, 9, 7, 8, 6, 5, 3, 4, 2, 1],函数应该返回 2,因为 [10,9,7,8,6,5, 3,4,2,1] → [10,8,4] → [10]
int numberOfTimes(int array[] , int n) {
int count = 0;
int flag = 0;
int sizeCounter = 0;
while (true){
for (int i = 0; i < n-1; ++i) {
if (array[i]<= array[i+1]){
sizeCounter++;
array[sizeCounter] = array[i+1];
} else{
flag = 1;
}
}
if (flag == 0)
return count;
count++;
flag = 0;
n = (sizeCounter+1);
sizeCounter = 0;
}
}
【问题讨论】:
-
如果您不需要返回计数,那么可以通过保持内存中看到的最大元素一次性完成。但是我很难找到一种以这种方式“猜测”计数的方法。虽然这确实让人想起一个有巧妙解决方案的经典问题,但如果我能再次找到它的话。
-
我没有完整的解决方案,但我会从识别峰、谷、下坡和上坡开始。例如,在数组 [10,5,3,4,6,8,7,1] 中,波峰为 10 和 8,波谷为 3 和 1,下坡为
10,5,3和8,7,1,以及上坡是3,4,6,8。一次通过即可消除下坡。上坡以每次 1 个元素的速度被移除。所以这个例子的计数是 4,因为最长的上坡有四个元素,峰 8 小于峰 10。 -
@wLui155 但是这个问题并不等价。考虑这个例子:array=[10,8,7,6,9] → [10,9] → [10]。答案是 2。但对于
i=4,我们得到j=0和i-j = 4. -
@Stef 不错。从这个意义上说,我对“距离”的定义并不完全正确。它应该与删除元素所需的轮数同义。事实证明,正确的“距离”定义是递归的,这让事情变得有点棘手:
distance[i] = max(distance[j]) + 1,对于每个j < i,如果是array[j] < array[i]。如果不存在这样的j,则distance[i] = 0。幸运的是,这个问题在线性时间内也是可以解决的,确实满足 10^5 的大小约束。 -
我基本上声称删除
array[i]所需的轮数是 1.0(array[i]未删除)2.1(它的邻居array[i - 1] > array[i]) 或 3. 找到最左边大于array[i],array[k]的元素。那么删除的次数是比删除索引k和i之间的一些中间元素的最大轮数多一倍。如上所述,问题看起来需要 O(N^2) 时间来解决,但通过一些巧妙的操作可以更快地完成。
标签: arrays c algorithm performance