问题描述
我们有一个由 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)