找到最大可能的S值(S =(min2∧min)),其中min2& min是最小的&数组的k个元素中的下一个最小整数

时间:2015-09-05 08:50:33

标签: arrays algorithm min

我正在处理编程问题。问题是:

给定N个不同元素的数组A []。令min2和min为区间[L,R]中的最小和下一个最小元素,其中1≤L<1。 ř≤Ñ

S =(min2∧min)。

其中∧是按位XOR运算符。 我必须找到S的最大可能值。

我已经编写了1个解决方案,它找到了S的最大可能值,但其复杂性很高。我在想是否可以进行优化。由于即使元素的范围k不固定,我也必须计算所有范围,即k = 2到数组的长度。 我使用的方法是首先将k取为2并从第0个元素开始,找到min&amp; min2在前k个元素中,计算S,如果它大于前一个S,则将其取为S,否则忽略它。从第一个元素开始,我在下一个k元素中找到min&amp;等等。与其他更高的范围相同,即3,4,5 ......以下是我写的代码:

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

public static void main(String[] args) {

    int num = 0, S = Integer.MIN_VALUE, min = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
    int[] input = null;

    try {
        BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
        String s = bufferRead.readLine();
        num = Integer.parseInt(s);
        s = bufferRead.readLine();
        String arr[] = s.split(" ");

        input = new int[arr.length];
        for(int i =0; i<arr.length;i++) {
            input[i] = Integer.parseInt(arr[i]);
        }
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }



    for(int k=2;k<=input.length;k++) {
         int j =0;

         while(j<input.length-k+1)
             {

             int i=j;

             for(i=j;i<(j+k);i++)
             {
             if(input[i] < min)
                 {
                 min2 = min;
                 min = input[i];
             }
                 else if(input[i] > min && input[i] < min2)
                 {
                 min2 = input[i];

             }


         }

         int st = (((min2 & min)^(min2 | min)) & (min2 ^ min));


         if(st > S)
             S = st;
            j++;
            min = Integer.MAX_VALUE;
            min2 = Integer.MAX_VALUE;
         }

        }
        System.out.println( S );

    }

}

这可以以某种方式加以优化吗?

1 个答案:

答案 0 :(得分:3)

这可以通过线性时间O(N)空间算法来完成。

为了简单起见,请将第二个最小元素放在最小元素之后。然后反转数组并再次执行(或者从最后一个元素开始向后处理数组)。

使用数组的每个元素作为区间(A[R])的最右边元素。现在,唯一被认为是间隔(A[L])最左边元素的元素是小于A[R]的最近元素(如果有的话)。 A[L]A[R]是此时间间隔的两个最小元素,因此请为它们计算S并在必要时更新结果。并且可以使用堆栈找到最近的较小元素。

的伪代码:

result = -infinity
for each X in array A:
    while NOT stack.empty AND stack.top > X: stack.pop
    if NOT stack.empty:
        result = max(result, X XOR stack.top)
    stack.push(X)
reverse array A and repeat

证明:该算法(确切地说,它的前半部分)尝试将数组的每个元素作为某个区间的第二个最小元素,使得(第一个)最小元素位于其左侧。显然,这考虑了区间A[L]..A[R]。此外,如果我们将此间隔扩展到任一侧(或两者)并且此扩展间隔的所有其他元素都大于A[R],那么A[R]仍然是第二个最小元素,并且此间隔也被考虑算法(但它不会改变S的最佳值)。如果至少有一个额外元素小于A[R]或者不是扩展,我们开始缩小间隔,A[R]不再是第二个最小元素,因此在这个特定迭代中不考虑这样的间隔(但是当我们尝试将其他元素作为第二大元素或当我们期望当前元素右边的第一大元素时,我们会考虑。)