在数组中查找元素,其中左元素较小而右元素较大?

时间:2016-06-27 12:05:27

标签: arrays algorithm data-structures

假设有一个数组,找出元素较小的元素和元素较大的元素。否则返回-1。我知道如何在O(n ^ 2)中做到这一点。但是如何在O(n)中完成呢?

O(n ^ 2)的代码:

#include <iostream>
using namespace std;
int main(){
int array[] = {5, 1, 4, 3, 2, 8, 10, 7, 9};
int sizeOfArray = sizeof(array)/sizeof(array[0]);
for (int i = 1; i < sizeOfArray-1; ++i) {
    int j = i-1;
    int k = i+1;
    while(array[j] < array[i] && array[k] > array[i]){
        if(j == 0 && k == sizeOfArray-1){
            cout << array[i];
            return 0;
        }
        if(j>0){
            j--;
        }
        if(k<sizeOfArray){
            k++;
        }

    }
}
cout << -1;
return 0;
}

4 个答案:

答案 0 :(得分:0)

1)从左到右扫描数组,记住到目前为止最大的值;

2)从右到左扫描数组,记住目前为止的最小值。

3)扫描两个新阵列,直到找到最大值不超过最小值。

示例:

3 6 4 5 9 8 7

3 6 6 6 9 9 9
3 4 4 5 7 7 7

没有解决方案。

3 2 4 6 9 8 7

3 3 4 6 9 9 9
2 2 4 6 7 7 7
    ^ ^

有两种解决方案。

实际上,两次扫描就足够了。

答案 1 :(得分:0)

// example with n2 complexity. 

class Elementwithleftsidesmallerandrightsidegreater {

  static void find(int[] arr) {

    for (int i = 1; i < arr.length; i++) {

        int head = arr[i];

        int left = i - 1;
        int right = i + 1;

        while (left >= 0 && arr[left] < head) {

            left--;
        }

        while (right < arr.length && arr[right] > head) {
            right++;
        }

        if (left == -1 && right == arr.length) {
            System.out.println("index is " + i);
            System.out.println("value is " + arr[i]);

        }

    }

  }

  public static void main(String[] args) {
    int arr[] = new int[] { 2, 1, 1, 3, 111, 80, 100, 79, 19 };

    find(arr);

  }
}

答案 2 :(得分:0)

这是O(3n)= O(n)的实现:

private static int findPivot(int[] a) {
    int length = a.length;
    int[] leftMax = new int[length];
    int[] rightMin = new int[length];
    leftMax[0] = a[0];
    for(int i=1; i<length; i++) {
        leftMax[i] = leftMax[i-1]>a[i]?leftMax[i-1]:a[i];  
    }

    rightMin[length -1] = a[length-1];
    for(int i=length-2; i>0; i--) {
        rightMin[i] = rightMin[i+1]<a[i]?rightMin[i+1]:a[i];  
    }

    int position = -1;
    for(int i=1; i<length-1; i++) {
        if(leftMax[i-1] < rightMin[i+1]) {
            position = i;
            break;
        }
    }

    return position;
}

以下是运行结果:

Initial array:  [5, -1, 3, 8, 6, 10]
Partitions:     [5, -1] 3 [8, 6, 10]
Initial array:  [5, 5, -2, -3, 0, 3, 8, 6, 10]
Partitions:     [5, 5, -2, -3, 0] 3 [8, 6, 10]
Initial array:  [3, -2, -2, -3, 0, 7, 2, 8, 6, 10]
Partitions:     [3, -2, -2, -3, 0, 7, 2, 8] 6 [10]

这是如何以这种方式打印它:

public static void main(String[] args) {
    int[] a = { 5, -1, 3, 8, 6, 10 };

    int pivot = findPivot(a);
    if (pivot != -1) {
        printPartitions(pivot, a);
    }
    int[] b = { 5, 5, -2, -3, 0, 3, 8, 6, 10 };
    int pivot1 = findPivot(b);
    if (pivot1 != -1) {
        printPartitions(pivot1, b);
    }
    int[] c = { 3, -2, -2, -3, 0, 7, 2, 8, 6, 10 };
    int pivot2 = findPivot(c);
    if (pivot2 != -1) {
        printPartitions(pivot2, c);
    }
}

private static void printPartitions(int pivot, int[] a) {
    System.out.println("Initial array:\t" + Arrays.toString(a));
    System.out.println("Partitions:\t" + Arrays.toString(Arrays.copyOfRange(a, 0, pivot)) + " " + a[pivot] + " "
            + Arrays.toString(Arrays.copyOfRange(a, pivot + 1, a.length)));
}

答案 3 :(得分:-1)

这是O(n):

我已经用JavaScript上的代码替换了我的算法描述,所以你可以简单地运行它,看看那里发生了什么。这段代码可以很容易地转换为C ++。

var arrayItems = [1, 3, 2, 3, 4, 6, 4, 7, 9, 10, 8];
var sizeOfArray = arrayItems.length;
var maxValue = arrayItems[0];
var pointValue = maxValue;
var elIndex = -1;
for (var index = 0; index < sizeOfArray; index++) {
  var set = false;

  // Check set of new point value
  if (-1 === elIndex && arrayItems[index] > maxValue) {
    pointValue = arrayItems[index];
    elIndex = index;
    set = true;
  }

  // Update max value
  if (arrayItems[index] > maxValue) {
    maxValue = arrayItems[index];
  }

  // Reset point value
  if (!set && -1 !== elIndex && arrayItems[index] <= pointValue) {
    pointValue = maxValue;
    elIndex = -1;
  }

  console.log([arrayItems[index], maxValue, pointValue, elIndex, index]);
}

console.log(elIndex);

当循环结束时,您将获得elIndex中的值:

 arrayItems:  1  3  2  3  4  6  4  7  9  10   8
   maxValue:  1  3  3  3  4  6  6  7  9  10  10
 pointValue:  1  3  3  3  4  4  6  7  7   7   7
    elIndex: -1  1 -1 -1  4  4 -1  7  7   7   7
      index:  0  1  2  3  4  5  6  7  8   9  10