查找数组中的int对数,该对中的所有值都小于或等于两者

时间:2016-09-08 01:56:41

标签: arrays algorithm

给定一个整数数组,找到int对的数量,这样对于每对a_i,a_j,它们之间的数字,即a_(i + 1)... a_(j-1)都小于或等于a_i和a_j。

显然:应该计算相邻的整数,比如a_i和a_(i + 1)。 并且很容易找到O(n ^ 2)算法。

我的问题是,是否有人有比O(n ^ 2)更好的解决方案?

2 个答案:

答案 0 :(得分:0)

我相信我在O(nlogn)中有它。

我们不必担心相邻的对,因为它们总是n-1;因此我们可以对它们进行折扣,只需将n-1添加到我们的最终结果中。

给定长度为arr的整数n数组,创建以下数据结构:

  1. 一系列dir长度为n-1的布尔值dir[i] = arr[i+1] > arr[i]。这些是移动方向,true正在增加,false正在减少。
  2. int的地图toPeak - > int,表示下降的所有toPeak.get(index)的{​​{1}}返回紧接index之前的相对最大值的索引。
  3. int的地图index - > int,表示上升的所有toValley的{​​{1}}返回紧接toValley.get(index)之前的相对最小值的索引。
  4. 然后继续算法:

    • 为此处的相邻对启动index //帐户
    • 然后你可以遍历索引index,并在每个索引:
      • 如果counter = n-1代表上升i <- 0...n-1
        • 找到i之前的山谷索引(dir[i])(在v中查找)
        • 查找i之前的峰值索引toValley(查询p
        • 二进制搜索区域v,查找最早,最接近的值等于或小于toPeak,在索引arr[p...v]处发生。
        • arr[i]
        • 增加x
    • 返回counter

    运行时很容易证明 - 创建每个数据结构需要(i-x),循环索引会导致counter次迭代,并且每次迭代需要O(n)时间进行二分搜索(假设{{ 1}}地图查找)。

    正确性更难,而且我不确定它是如何以相同的价值观展开的。现在考虑一下。

答案 1 :(得分:0)

我会递归地解决它。我认为不可能定义复杂性。 所以让我们开始(为了简化代码,我不收集它们,只是在屏幕上打印):

void check_next(int*my_arr,int count,int cur_max) 
{
  int temp;
  if(!count || (temp=*my_arr) < cur_max)
       return;
   printf("%d\n",*my_arr);
     check_next(++my_arr,--count,temp);         
}
 void main()
{
  check_next(array,sizeof(array)/sizeof(int),array[0]);
}