两个和:2个数组中的元素等于预定的Sum Swift 3

时间:2017-09-14 03:53:24

标签: arrays swift

如果我有两个数组,并想知道每个数组中的元素(Int)是否等于预定义值(Int),我该怎么做。我是Swift的新手,有点迷失。

func twoSum(a:[Int], b:[Int], c: Int) -> Bool {
     // iterate through arrays to see if an element in each equal c
     return false // if no values equal the sum c 
}

twoSum(a: [1,3,4,5], b: [1,3,4,5], c: 10)

我不需要将数组转换为集合,但我想知道如何有效地迭代这两个数组。如果没有一堆for或if循环,我该怎么做?

3 个答案:

答案 0 :(得分:1)

一种解决方案可以是:

使用filter查看a是否包含bc中每个值的差异,如果是,那么filter返回的数组不会为空,函数将返回true,否则为false

func twoSum(a:[Int], b:[Int], c: Int) -> Bool {

        return !b.filter {a.contains(c-$0)}.isEmpty

}

答案 1 :(得分:1)

最佳解决方案是套装。由于contains对集合的O(1)操作。但正如你所提到的,你不想使用套装。以下是另一种在O(nlogn)时间内有效的解决方案。

func twoSum(a:[Int], b:[Int], c: Int) -> Bool {
    let sortedA = a.sorted()
    let sortedB = b.sorted()
    var i = 0, j = sortedB.count - 1
    repeat {
        let sum = sortedA[i] + sortedB[j]
        if sum == c {
            return true
        } else if sum < c {
            i += 1
        } else {
            j -= 1
        }
    } while( j >= 0 && i < sortedA.count)

    return false
}

答案 2 :(得分:0)

嵌套循环:

func twoSum(a:[Int], b:[Int], c: Int) -> Bool {
  for aVal in a {
    for bVal in b {
      if aVal + bVal == c {
        return true
      }
    }
  }
  return false
}

这会将a中的每个元素与b中的每个元素相加并返回true,如果任何总和等于cfalse,如果没有他们这样做。正如@LeoDabus指出的那样,如果找到匹配项,则早期return true将导致函数在找到单个匹配项后立即退出。这甚至可以是第一次添加和比较。这非常有效率。

总和将如下:

a[0] + b[0]
a[0] + b[1]
...
a[1] + b[0]
a[1] + b[1]
...
a[n] + b[n]

另一种选择是:

func twoSum(a:[Int], b:[Int], c: Int) -> Bool {
  // thanks to @3stud1ant3 for the idea of using a difference
  let diff = Set(a.map { c - $0 })
  return !diff.isDisjoint(with: b)
}

当然,这只是在其他方法中隐藏了一些循环。 map当然使用一个isDisjoint使用哈希表来查找匹配项 - 可能有一个或多个循环。