确定前两个元素的逻辑 AND 最大的子数组

问题描述

我们有一个由 n 个整数组成的数组,我们需要确定前两个元素的逻辑 AND 最大的子数组。我们需要返回左右索引。

样本输入:3 3 5

输出:0 1

我尝试了以下解决方案:

List<Integer> list = new LinkedList<>();
List<Integer> llist = new LinkedList<>();
    int max = Integer.MIN_VALUE;
    
    for(int i =0; i < arr.size(); i ++){
        for(int j=i+1; j < arr.size(); j++ ){
            int a = arr.get(i);
            int b = arr.get(j);
            
            if((a & b) > max){
                max = (a & b);
                list.clear();
                list.add(i);
                list.add(j);
            }
            else if((a & b) == max){
                list.add(i);
                list.add(j);
            }
        }
    }
    
    if (list.size() > 2) {
       llist.add(list.get(0));
       llist.add(list.get(1));
       return llist;
    }

    return list;
}

复杂度为 n 平方阶。我们可以优化这个吗? 有没有更好的方法解决这个问题?有人可以指导我吗。

解决方法

根据您的代码,如果您只需要一个结果(第一个最好)并假设二进制补码整数格式,您可以这样做:

   List<Integer> list = new LinkedList<>();
  int max = arr.get(0) & arr.get(1);
  int bestAind=0; bestBind=0;
  int OnesMask = Integer.MAX_VALUE; //Needed when using negative values

    for(int i =0; i < arr.size(); i ++)
    {
        int a = arr.get(i);

        if(a & OnesMask <max)
           continue;

        for(int j=i+1; j < arr.size(); j++ )
        {           
            int b = arr.get(j);
            
            if((a & b) > max){
                max = (a & b);
                bestAind = i;
                bestBind = j;
            }            
        }
    }
    
    if (bestAind != bestBind ) {
       list.add(bestAind );
       list.add(bestBind );
    }

    return list;
}

这可能会减少一点处理时间,但这将取决于数组的初始排序。最好情况 O(n),最坏情况 O(n^2)