在整数数组中查找第一个不重复的数字

Finding first non-repeating number in integer array

本文关键字:数字 第一个 整数 数组 查找      更新时间:2023-10-16

我的考试题目是:

给定一个整数数组,用O(N)的时间复杂度和O(1)的空间复杂度找到数组中第一个不重复的数字

我想不出任何解决办法。我知道我可以遍历数组并维护一个linkedhashmap,它将存储数组元素和它出现的次数,然后最后我必须搜索hashmap来找到那个数字。空间复杂度大于0(1)但我想不出其他的解决方案。

我也仔细阅读了问题,说数组的最大大小将是100万。我认为,如果我们可以创建一个自定义哈希映射,它将利用一个固定大小的100万大小的数组,那么这可以在0(1)空间复杂度中实现,因为在这种情况下,所需的存储将是恒定的,但更确定如果我是正确的。如果有其他的解决办法,请告诉我。

如果除一个元素外的所有元素都有两个(或2的倍数)条目,且该元素不重复,则可以使用异或运算符。

的例子:

int x=arr[0];
for(i=1;i<1000;i++)
  x^=a[i];
printf("Non-repeating: %d",x);

任何数与自身相乘等于0。因此,如果任何数字出现两次,那么它在整个异或结果中将为0,从而只在x中留下不重复的数字。

注意:如果您有100万个数字,用于存储异或结果的变量必须足够大

查找给定整数数组中的第一个非重复数

更新:找到更好的解决方案。我认为我们可以使用额外的数据结构(如HashMap)来解决O(n)时间复杂度问题。遍历数组,并将元素作为键,并将元素在数组中的索引位置作为映射中的值。如果键已经存在,可以删除键-值对,或者将值设置为-1。一旦遍历了整个数组,我们就可以从hashmap中获得keySet(),然后找到值最小的键(忽略-1)。所以这是时间复杂度:0 (N)空间复杂度:O(N)

旧的解决方案:我们可以通过创建另一个数组来解决这个问题,这个数组是通过对给定数组进行排序得到的。这需要O(nlogn)时间。然后我们可以遍历给定输入数组中的每个元素,尝试找到元素&与已排序数组中的下一个元素比较,如果重复,则继续查找给定数组中的下一个元素,如果不重复,则找到给定输入整数数组中第一个不重复的元素。

时间复杂度:O(nlogn)
空间复杂度:O(n)

p。S:很抱歉,我没有看到所有的评论,James Kanze已经在评论中提供了这个解决方案,感谢他。

我使用的是PowerShell

[int[]]$arr = @(6,2,1,2,6,1,7)
$Collection = New-Object 'System.Collections.Generic.list[System.Object]'
$props=[ordered]@{"Index"=9999;"Value"=9999;"Numcount"=9999}
$record = New-Object -TypeName psobject -Property $props
$Collection.Add($record) #This record is added to do a Contains operation 
#for future items to be added in the $collection object
for($i =0;$i -lt $arr.Length;$i++)
{
if($i -eq 0)
{
    $props=[ordered]@{"Index"=$i;"Value"=$arr[$i];"Numcount"=1}
    $record = New-Object -TypeName psobject -Property $props
    $Collection.Add($record)
}

elseif($Collection.value.Contains($arr[$i]))
{
    $count = ($Collection | ?{$_.Value -eq $arr[$i]} | select -First `
1).Numcount
    ($Collection | ?{$_.Value -eq $arr[$i]} | select -First 1).Numcount = `
$count+1
}
else
{
    $props=[ordered]@{"Index"=$i;"Value"=$arr[$i];"Numcount"= 1}
    $record = New-Object -TypeName psobject -Property $props
    $Collection.Add($record)
}
}
Write-Output "The first non repeating number in the array is listed below"
$Collection | Sort-Object Numcount -Descending | ?{$_.Numcount -eq 1} | 
Select -First 1
OUTPUT:-
The first non repeating number in the array is listed below
Index Value Numcount
----- ----- --------
6     7        1

我相信解决这个问题的诀窍是:

数组的最大大小为100万

自:

0(1)空间表示算法所需的内存常数

,则给定1M不变,空间复杂度将自动变为O(1)。请注意。1M仍然是一个常数,尽管它是一个很大的数。因此,我们只需要关注时间复杂度。

使用LinkedHashMap,我们可以使用O(1)添加一个新元素,并使用O(1)检索元素,因此更新一个条目也将花费O(1)。它也是preserves the order。因此,我们可以找到最早的条目

那么问题就变得简单了,分两步:

  1. 建立LinkedHashMap -> 0 (n)
  2. 查找其计数为0 -> 0 (n)

以上每一步都需要O(n),因此总的time complexityO(2n) = O(n)