我有一个函数,它接受一个N正整数的一维数组,并返回大于下一个整数的元素数。问题是存在一个功能,在更好的时间做到这一点?我的代码如下:
int count(int *p, int n) {
int i, j;
int countNo = 0;
int flag = 0;
for(i = 0; i < n; i++) {
flag = 1;
for(j = i + 1; j < n; j++) {
if(p[i] <= p[j]) {
flag = 0;
break;
}
}
if(flag) {
countNo++;
}
}
return countNo;
}
我的解决方案是O(n^2)
。可以做得更好吗?
答案 0 :(得分:4)
您可以在线性时间(O(n) time
)中解决此问题。请注意,数组中的最后一个数字始终是适合问题定义的有效数字。因此该函数将始终输出一个大于等于1的值。
如果数组中的任何其他数字是有效数字,则它必须大于或等于数组中该数字后面的最大数字。
因此,从右到左遍历数组,跟踪到目前为止找到的最大数字,如果当前数字大于或等于到目前为止发现的最大值,则递增计数器。
int count2(int *p, int n) {
int max = -1000; //this variable represents negative infinity.
int cnt = 0;
int i;
for(i = n-1; i >=0; i--) {
if(p[i] >= max){
cnt++;
}
if(p[i] > max){
max = p[i];
}
}
return cnt;
}
时间复杂度:O(n)
空间复杂度:O(1)
答案 1 :(得分:1)
创建辅助阵列aux
:
aux[i] = max{arr[i+1], ... ,arr[n-1] }
通过从右到左扫描数组,可以在线性时间内完成。
现在,您只需要arr[i] > aux[i]
这是在O(n)
。
答案 2 :(得分:1)
向后走过数组,并跟踪当前的最大值。无论何时找到新的最大值,该元素都大于后面的元素。
答案 3 :(得分:1)
可以在O(n)
中完成。
int count(int *p, int n) {
int i, currentMax;
int countNo = 0;
currentMax = p[n-1];
for(i = n-1; i >= 0; i--) {
if(currentMax < p[i])
{
countNo ++;
currentMax = p[i];
}
}
return countNo;
}
答案 4 :(得分:1)
是的,可以在O(N)
时间内完成。我会告诉你一个如何去做的方法。如果我正确理解了您的问题,那么您需要的元素数量大于数组中接下来的所有元素,只要维持订单。
所以:
Let len = length of array x
{...,x[i],x[i+1]...x[len-1]}
We want the count of all elements x[i] such that x[i]> x[i+1]
and so on till x[len-1]
从末尾开始遍历数组,即i = len -1
,并跟踪您遇到的最大元素。
可能是这样的:
max = x[len-1] //A sentinel max
//Start a loop from i = len-1 to i = 0;
if(x[i] > max)
max = x[i] //Update max as you encounter elements
//Now consider a situation when we are in the middle of the array at some i = j
{...,x[j],....x[len-1]}
//Right now we have a value of max which is the largest of elements from i=j+1 to len-1
因此,当您遇到大于x[j]
的{{1}}时,您基本上找到了一个比下一个元素更大的元素。你可以只有一个计数器并在发生这种情况时增加它。
伪代码显示算法的流程:
max
所以最终 counter = 0
i = length of array x - 1
max = x[i]
i = i-1
while(i>=0){
if(x[i] > max){
max = x[i] //update max
counter++ //update counter
}
i--
}
将包含您需要的元素数量。
希望我能够解释你如何解决这个问题。编码这应该是一个有趣的练习作为起点。