Java 如何修复N/3重复编号的此代码

Java 如何修复N/3重复编号的此代码,java,Java,我是从面试开始做这个问题的 您将得到一个由n个整数组成的只读数组。找出是否有整数 以线性时间和常量在数组中发生n/3次以上 额外空间 如果是,则返回整数。如果没有,返回-1 如果有多个解决方案,请返回任意一个 例如: 输入:[1 2 3 1] 产出:1 1发生3次,超过5/3次 这是我的密码,它给出了错误的答案,任何人都能纠正我的错误 public class Solution { // DO NOT MODIFY THE LIST public int repeatedNu

我是从面试开始做这个问题的

您将得到一个由n个整数组成的只读数组。找出是否有整数 以线性时间和常量在数组中发生n/3次以上 额外空间

如果是,则返回整数。如果没有,返回-1

如果有多个解决方案,请返回任意一个

例如:

  • 输入:[1 2 3 1]
  • 产出:1

    1发生3次,超过5/3次

这是我的密码,它给出了错误的答案,任何人都能纠正我的错误

public class Solution {
    // DO NOT MODIFY THE LIST
    public int repeatedNumber(final List<Integer> a) {
        int size =a.size();
        double c=size/3;
        int num=0;
        int n=0,m=1,l=size-1;
        double count=1;
        while(l>m && size>=3){
            if(a.get(n)==a.get(m) && a.get(n)!=a.get(l)){
                num=a.get(n);
                l--;
                count=count+1;
            }else if(a.get(n)==a.get(l) && a.get(n)!=a.get(m)){
                num=a.get(n);
                l--;
                count+=1;
            }else if(a.get(m)==a.get(l) && a.get(n)!=a.get(m)){
                num=a.get(m);
                l--;
                count+=1;
            }else if(a.get(n)==a.get(m)&& a.get(n)==a.get(l)){
                num=a.get(n);
                l--;
                if(count>0){
                    count+=1;
                }else{
                    count+=2;
                }
            }else{
                n++;
                m++;
                l--;
            }
        }
        if(count>1&& count>c){
            return num;
        }else{
            return -1;
        }
    }
}

A : [ 1000441, 1000441, 1000994 ]

Your function returned the following :

-1
公共类解决方案{
//不要修改列表
公共整数重复编号(最终列表a){
int size=a.size();
双c=尺寸/3;
int num=0;
int n=0,m=1,l=size-1;
重复计数=1;
而(l>m&&size>=3){
如果(a.get(n)=a.get(m)&&a.get(n)!=a.get(l)){
num=a.get(n);
l--;
计数=计数+1;
}else如果(a.get(n)==a.get(l)&a.get(n)!=a.get(m)){
num=a.get(n);
l--;
计数+=1;
}else如果(a.get(m)==a.get(l)&a.get(n)!=a.get(m)){
num=a.get(m);
l--;
计数+=1;
}else如果(a.get(n)==a.get(m)&&a.get(n)==a.get(l)){
num=a.get(n);
l--;
如果(计数>0){
计数+=1;
}否则{
计数+=2;
}
}否则{
n++;
m++;
l--;
}
}
如果(计数>1&&计数>c){
返回num;
}否则{
返回-1;
}
}
}
答:[1000441100994]
您的函数返回了以下内容:
-1
预期的返回值:

出现n/3次以上的任何数字


这是输出

您的代码有几个问题

您现在遇到的主要问题是将整数对象与
==
进行比较。 这将检查引用是否相同。他们似乎不是。 值是否相同并不重要,因为它仍然是两个不同的整数对象(可能是列表的“错误”,因为从技术上讲,您可以创建两个不同的整数对象,使用
=
操作符计算为true)

正确执行此操作的最简单方法是使用:

a.intValue() == b.intValue()

后者的效率稍低,但编写的代码更少

我想提的另一件事是

double c=size/3;
size
是整数,
3
也是整数。因此,即使您的
大小
5
c
也将为
1.0

这是因为发生的第一件事是计算
5/3
(因为它们都是整数)将是
1
。然后将该
1
赋值给一个双变量,使其
1.0
。 如果您想要得到正确的结果,您需要将这两个值中的一个转换为double(除非您在这种情况下不需要它:为什么要使用double?)

最后一件事: 您现在的代码无法用于更复杂的示例。
但这是一个完全不同的问题,会导致“为你做家庭作业”的问题,所以我现在不讨论这个问题。一旦你被困在其他地方,只需问一个新问题。

因为你想用
线性
复杂度来实现它,你可以为此使用
HashMap
,并保持最大计数,如果它大于
n/3
,你可以返回
true
。 代码:

公共布尔校验计数(int[]数组,int n){
int maxCount=0;
Map numberCountMap=新的HashMap();
对于(int i=0;i maxCount){
最大计数=计数;
}
}
如果(最大计数>=n/3){
返回true;
}否则{
返回false;
}
}
HashMap
中,键是数组中的
number
,其值是
其总计数
。因此,最初它将检查它是否存在于
map
中,然后
增加它的值。还将该值与
maxCount
进行比较。因此,最后如果
maxCount
大于或等于
n/3
则为
true
else
false

所以对于输入数组:[1,2,1,4,6,1,1],它给出了输出:true


你能解释一下你的代码是如何工作的吗?从技术上讲,如果所有的数字都是
整数
,你可以使用一个大小为
整数.MAX_VALUE
的数组来计算各个数字,这将完全满足“恒定附加空间”的限制:-因为O(n)的复杂性,我们需要解决这个问题。所以我用了三个变量n,m和l。现在在while循环中。它检查情况。对于给定的测试用例,正如您在while循环中看到的,如果条件是静态的,但我仍然得到了错误的答案。请检查一下。你的评论并不能解释算法是如何工作的。(这可能适用于测试用例,但一般情况如何?)这三个变量应该代表什么,条件意味着什么?我不明白你的算法应该如何工作。在我看来,您似乎是在相互比较随机整数实例。不确定如何查找重复次数最多且超过n/3次的整数。无论如何-当您使用equals运算符比较整数实例时,if语句的计算结果永远不会为true。使用调试器找到。通常,整数引用不会指向同一实例,即使它们具有相同的值。因此,您应该使用
equals()
方法进行比较。。。而且,它不会返回带有该计数的数字。相反地,我是y
double c=size/3;
public boolean checkCount(int[] array, int n) {
    int maxCount = 0;
    Map<Integer,Integer> numberCountMap = new HashMap<>();
    for(int i=0;i<array.length;i++){
        int number = array[i];
        int count = numberCountMap.getOrDefault(number,0);
        numberCountMap.put(number, ++count);
        if(count > maxCount){
            maxCount = count;
        }
    }
    if(maxCount >= n/3){
        return true;
    }else{
        return false;
    }
}