在给定的排列中找到缺失的元素

Find the missing element in a given permutation

首先,一些背景知识:

我正在研究 the Codility lessons 之一,尽管这很容易解决,但从逻辑上讲,在性能方面并不容易解决。

我已经能够将其归结为:

public func solution(_ A : inout [Int]) -> Int {
    let B = A   // Assigning it to a local speeds it up.
    return Array<Int>(Set(B)).sorted(by: {[=10=]<}).reduce(0) { ( == [=10=] + 1) ?  : [=10=] } + 1
}

但是,这只是 WEE 有点太慢了。我想主要原因是 reduce 遍历了数组的所有元素,即使答案可能很早。我可能无法加快速度。

但我想试试。我正在查看的部分是:

.reduce(0) { ( == [=11=] + 1) ?  : [=11=] }

我想知道我是否可以使比较更有效率。

我必须检查 $1 是否等于 $0 + 1。我无法避免这种比较。

三元运算符实际上并不比 if 子句快,但它看起来更酷 ;)。

是否有比基本的“==”运算符更高效的方法来比较两个正整数是否相等?

顺便说一句:这不是 "do my homework for me" 问题。这是非常合法的,这些 Codility 课程不会给你信用或任何东西。它们只是一个有趣的练习。我想知道如何做到这一点,因为我确定我将来会需要它。

使用@TNguyen 在评论中建议的解决方案,下面的代码段在正确性和性能上都达到了 100%。

您只需生成正确的数组,通过调用 Array(1...A.count+1) 包含 [1..(N + 1)] 范围内的每个整数。然后使用 reduce(0,+) 对其元素求和,最后减去输入数组元素的总和 A。两个总和之间的差值给出了缺失的元素。

public func solution(_ A : inout [Int]) -> Int {
    return Array(1...A.count+1).reduce(0,+)-A.reduce(0,+)
}

一个更快的解决方案是使用数学公式1+2+...+n=n(n-1)/2 计算第一个总和。

public func solution(_ A : inout [Int]) -> Int {
    return (A.count+1)*(A.count+2)/2-A.reduce(0,+)
}

python 100% 得分使用其他概念:

def solution(A):
 Index=0;
 while (Index<len(A)):
  while((A[Index]-1) != Index and A[Index]<=len(A)):
   Tmp=A[Index]; #Permut
   A[Index]=A[Tmp-1];
   A[Tmp-1]=Tmp;
  Index+=1;
 Index=0;
 while Index<len(A):
  if((A[Index]-1) != Index) :
   return Index+1;
  else:
   Index+=1;
 return len(A)+1;  
pass

背后的想法是,对于给定的排列,每个元素 A[Index]-1 都应该与 Index 匹配,但缺少的元素除外。然后排列数组的元素,直到当 A[Index]>len(A) 时达到或不达到对应为止。