Need to loop through an array and say whether there are any pairs of numbers that sum to 8
e.g. [1,2,4,4] = yes
Can get it working with lots of nested if stateme
You want to check all sums numbers[i] + numbers[j]
where
i < j
, and the easiest way to do so is a nested loop like this:
func checkPairs(in numbers: [Int], forSum target: Int) -> Bool {
for i in 0..
The array lookups can be avoided by using the enumerated()
method
and array slices:
func checkPairs(in numbers: [Int], forSum target: Int) -> Bool {
for (i, x) in numbers.enumerated() {
for y in numbers[i+1 ..< numbers.count] {
if x + y == target {
return true
}
}
}
return false
}
Here x
is the current element of the outer loop and i
its
index. y
is the current element of the inner loop which starts
enumerating at i + 1
.
Example:
print(checkPairs(in: [1, 2, 4, 4], forSum: 8))
print(checkPairs(in: [1, 2, 4, 4], forSum: 7))
The above function could be written more compactly as
func checkPairs(in numbers: [Int], forSum target: Int) -> Bool {
return numbers.enumerated().contains(where: { (i, x) -> Bool in
numbers[i+1 ..< numbers.count].contains(target - x)
})
}
If the given numbers are in non-decreasing order then you can improve the performance by terminating the inner loop if the target sum cannot be reached:
func checkPairs(in numbers: [Int], forSum target: Int) -> Bool {
for (i, x) in numbers.enumerated() {
for y in numbers[i+1 ..< numbers.count] {
if x + y == target {
return true
}
if x + y > target {
break
}
}
}
return false
}
For an array of non-decreasing numbers an even more efficient
solution would be to do a binary search for target - x
for each array element x
. Here is a possible binary search
implementation (a variant of https://stackoverflow.com/a/40226976/1187415):
extension Collection where Iterator.Element: Comparable {
func binarySearch(element: Iterator.Element) -> Bool {
var low = startIndex
var high = endIndex
while low != high {
let mid = index(low, offsetBy: distance(from: low, to: high)/2)
if self[mid] < element {
low = index(after: mid)
} else if element < self[mid] {
high = mid
} else {
return true
}
}
return false
}
}
which can then be used as
func checkPairs(in numbers: [Int], forSum target: Int) -> Bool {
return numbers.enumerated().contains(where: { (i, x) -> Bool in
numbers[i+1 ..< numbers.count].binarySearch(element: target - x)
})
}