当我执行这个时,即使没有重复,它也显示为真。基本上,它对我输入的每个数组都显示为真。我不知道为什么它会显示给我。我会很感激这个问题的一些帮助!谢谢!
public static boolean Duplicate()
{
int [] duplicateArray = new int[5];
System.out.print("Enter your array numbers:");
System.out.println();
for(int i = 0; i < duplicateArray.length; i++)
{
Scanner in = new Scanner(System.in);
duplicateArray[i] = in.nextInt();
}
boolean same = false;
for(int i = 0; i < duplicateArray.length-1; i++)
{
for(int j = 0; j < duplicateArray.length; j++)
{
if(i==j)
{
same = true;
}
}
}
return same;
}
答案 0 :(得分:0)
您正在比较数组偏移量,而不是这些偏移量处的值。
这个
if(i==j)
应该
if(duplicateArray[i]== duplicateArray[j])
也就是说,你的算法效率很低。至少,一旦检测到重复,您就应该中断循环。最简单的方法是立即 return true
(这样您就不需要 same
变量。
一种更有效的方法是对数组进行排序,然后将每个索引与前一个索引进行比较。这给了你 O(n log n) 而不是 O(n^2) 的最坏情况复杂度。
答案 1 :(得分:0)
所以,代码中有
if (i==j) {
same = true;
}
您比较的是诱导,而不是价值。您必须跳过比较同一索引处的值,如下所示:
if (i==j) {
continue;
}
if (duplicateArray[i] == duplicateArray[j]) {
same = true;
break;
}
答案 2 :(得分:0)
正如其他人所说,您代码中的问题在于您比较的是索引 (i and j
) 而不是值 (duplicateArray[i] and duplicateArray[j]
)。
因此,改变
if (i == j)
到
if (duplicateArray[i] == duplicateArray[j])
应该可以解决您的问题。
但是,为了改进您的解决方案(目前是一个 O(n^2)
算法,因为您有两个遍历整个数组的嵌套循环),这里有几种方法:
true
:基本上,而不是
same = true;
你可以这样做
return true;
因为你不关心数组的其余部分;你已经找到了一对。
虽然这不会改善渐近运行时的复杂性,但它会通过提前终止来加速您的代码。
我们可以使用 Arrays.sort(duplicateArray);
按升序对数字进行排序,只需 O(n log n)
次。现在,我们保证相等的元素将彼此相邻,这意味着我们可以在 O(n)
之后的时间内找到答案。
代码看起来像这样(在您收到输入之后):
Arrays.sort(duplicateArray);
for (int i = 1; i < duplicateArray.length; i++) {
if (duplicateArray[i] == duplicateArray[i - 1]) {
return true;
}
}
return false;
这将您的运行时复杂性降低到 O(n log n)
HashSet
:HashSet
有一个 .contains()
方法,它在预期的 O(1)
时间内运行。因此,如果我们将已经遍历过的每个数字添加到 HashSet
中,我们可以在恒定时间内检查相等性。因此,遍历数组需要 O(n)
时间,因此我们可以改进 O(n log n)
解决方案。
代码看起来像这样(再次输入后):
Set<Integer> set = new HashSet<>();
for (int i = 0; i < duplicateArray.length; i++) {
if (set.contains(duplicateArray[i])) {
return true;
}
set.add(duplicateArray[i]);
}
return false;
唯一的问题是 HashSet
会占用额外的空间。