算法 - 具有较小元素的最大左子数组

时间:2017-08-09 07:48:59

标签: java arrays algorithm

我正在开发一个程序,我需要在整数数组中获取元素索引,这样索引右边的所有元素都大于0到索引位置的所有元素。

例如:

Case : 1 - 给定输入 - { 5, -2, 3, 8, 6 }然后我需要索引位置为2 (i.e array element with value 3),因为索引2之后的所有元素都大于从索引0开始到索引的所有元素2即{5,-2,3}

Case : 2 - 给定输入 - { -5, 3, -2, 8, 6 }然后我需要索引位置为2 (i.e array element with value -2),因为索引2之后的所有元素都大于从索引0开始到索引的所有元素2即{-5,3,-2}

这是我的Java程序:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ArrayProgram {

    public static void main(String[] args) {
        int[] array1 = { 5, -2, 3, 8, 6 };
        int[] array2 = { -5, 3, -2, 8, 6 };
        process(array1);
        process(array2);
    }

    private static void process(int[] array) {
        List<Integer> list = new ArrayList<Integer>();
        int maxIndex = 0;
        list.add(array[0]);
        System.out.println(Arrays.toString(array));
        for (int i = 1; i < array.length; i++) {
            if (array[i] <= Collections.max(list)) {
                list.add(array[i]);
                maxIndex = i;
            }
        }

        System.out.println("index = " + maxIndex + ", element = " + array[maxIndex]);
    }
}

程序输出为:

[5, -2, 3, 8, 6]
index = 2, element = 3
[-5, 3, -2, 8, 6]
index = 0, element = -5

适用于case 1,但case 2失败。你可以帮我解决这个问题。有没有其他更好的方法来解决这个问题,

3 个答案:

答案 0 :(得分:5)

不幸的是,您的解决方案有几个逻辑错误。其中一个反例:[2, 1, 3, 6, 5](您的算法返回索引1,但答案是2)。

我提出了O(n)时间复杂度的另一种解决方案:

  1. 从左向右迭代计算[0..i]区间中元素的最大值。
  2. 从右向左迭代计算[i+1..n]区间中元素的最小值,并将此最小值与在第一步预先计算的左侧元素的最大值进行比较。
  3. 示例实施:

    static void process(int[] array) {
        int n = array.length;
        if (n < 2) return;
    
        int[] maxLeft = new int[n];
        maxLeft[0] = array[0];
        for (int i = 1; i < n; ++i) {
            maxLeft[i] = Math.max(maxLeft[i-1], array[i]);
        }  
    
        int minRight = array[array.length-1];
        for (int i = n-2; i >= 0; --i) {
            if (maxLeft[i] < minRight) {
                System.out.println("index = " + i + ", element = " + array[i]);
                return;
            } 
            minRight = Math.min(minRight, array[i]); 
        }
    }    
    

    Runnable:http://ideone.com/mmfvmH

答案 1 :(得分:2)

更改了我的评论以回答。从数组末尾开始只有一个元素,左边将有n - 1个元素。然后检查最大左边&lt;如果满足则完成对的最小值,然后将索引向左移动并再次检查。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ArrayProgram {

    public static void main(String[] args) {
        int[] array1 = { 5, -2, 3, 8, 6 };
        int[] array2 = { -5, 3, -2, 8, 6 };
        int[] array3 = { 1, 3, 5, 8, 4 };
        int[] array4 = { 1, 1, 1, 1, 1 };
        process(array1);
        process(array2);
        process(array3);
        process(array4);
    }


    private static void process(int[] array) {
        List<Integer> listLeft = new ArrayList<Integer>();
        List<Integer> listRight = new ArrayList<Integer>();

        //create an array that consists upto n-1 elements
        int arraySize = array.length;
        if ( arraySize < 2){
            System.out.println("None");
            return;
        }
        for ( int i = 0; i < arraySize - 1; i++){
            listLeft.add ( array[i]);
        }
        //create an array that has the last element
        listRight.add ( array[arraySize - 1]);

        //iterate from the last adding new elements till the condition satisfies
        for ( int i = arraySize - 2; i >= 0; i--){

            //if the condition is satisfied exit
            if ( Collections.max(listLeft) < Collections.min(listRight)){
                System.out.println("index = " + i + ", element = " + array[i]);
                return;
            }else{
                //remove an element from left and add an element to right
                listLeft.remove (listLeft.size() - 1);
                listRight.add ( array[i]);
            }
        }

        System.out.println("None");
    }
}

答案 2 :(得分:0)

我建议使用一种算法来获得正确的输出。它将在O(n)中执行。让我们考虑n中有arr[]个元素。维护2个数组int minElementIndex[]maxElementIndex[]

  • minElementIndex[i]存储子阵列[(i + 1)...(n-1)]中存在的最小值元素的索引。 minElementIndex[n-1]=n-1
  • 的值
  • maxElementIndex[i]存储子数组[0 ...(i)]中存在的最大值元素的索引。 maxElementIndex[0]=0
  • 的值

填写minElementIndex [0 ... n-1]

的代码
int index=minElementIndex[n-1];
for(int i=n-2;i>=0;i--){
  minElementIndex[i] = index;
  if(arr[i]<arr[index])
      index=i;
}

填写maxElementIndex [0 ... n-1]的代码:

int index=maxElementIndex[0];
for(int i=1;i<n;i++){
  if(arr[i]>arr[index])
     index=i;
  maxElementIndex[i]=index;
}

现在,只需按以下方式遍历两个数组:

for(int i=1;i<n-1;i++){ 
    if(arr[maxElementIndex[i]]< minElementIndex[i]){
        System.out.println(i);
    }
}

让我们继续运行所提出的算法。

案例1: arr[5] = {5,-2,3,8,6} minElementIndex[5] = {1,2,4,4,4}maxElementIndex[5] = {0,0,0,3,3}。显然是i=2arr[maxElementIndex[i]] < arr[minElementIndex[i]] 5 < 6

案例2: arr[5] = {-5,3,-2,8,6} minElementIndex[5] = {2,2,4,4,4}maxElementIndex[5] = {0,1,1,3,3}。显然是i=2arr[maxElementIndex[i]] < arr[minElementIndex[i]] 3 < 6