Problem overview
The method find receives an array of integers, nums, and an integer value. It returns the index of value in the array, or -1 when the value isn't there. For nums = [1, 2, 4, 5] and value = 4 the answer is 2, because nums[2] is 4.
The lesson asks for O(n) time and O(1) extra space.
Approach: check every position in order
With no information about the array, the only way to be sure a value is missing is to look at every element. So the plan is to go from the first position to the last, compare each element with value, and stop as soon as one matches. If the end is reached with no match, the value isn't present.
The answer is a position, not a value, so the loop must carry an index. A loop such as for num in nums hands you the values only, and you would have to count positions by hand. Looping over the indices 0..<nums.count gives you both: the index i and the element nums[i].
Step by step
- Loop over every index.
for i in 0..<nums.countruns from 0 to the last valid index. - Compare and return early. If
nums[i] == value, returniat once. This ends the function at the first match, so when the value occurs several times, the lowest index is returned. - Return -1 after the loop. The line is reached only when no comparison matched. A negative number can't be an index, so it can't be confused with a real result.
The solution in Swift
class Solution {
func find(_ nums: [Int], _ value: Int) -> Int {
for i in 0..<nums.count {
if nums[i] == value {
return i
}
}
return -1
}
}
Swift details worth knowing:
- Half-open range.
0..<nums.countexcludes its upper bound, so the largest index used isnums.count - 1. For an empty array the range is empty and the body never runs. - Return from inside a loop. A
returnleaves the whole method, not just the loop. That is what makes the search stop early. - The final
return -1is required. The compiler insists that every path returns anInt. Without that line, the method reports "missing return in instance method expected to return 'Int'". - Optionals are the alternative. Swift code often returns
Int?for "maybe a position", withnilfor not found. This lesson uses-1instead, as the return type is a plainInt. - Labels. Both parameters use
_, so a call looks likefind([1, 2, 4, 5], 4).
Complexity
Time: O(n) for an array of n elements. In the worst case, when the value is last or absent, the loop does n comparisons. A match near the front finishes sooner, but the bound covers the worst case.
Space: O(1). The only extra memory is the loop index.
Edge cases and common mistakes
- Not found.
[1, 2, 4, 5]withvalue = 9returns-1. - Empty array. The loop doesn't run and the result is
-1. - Duplicates.
[3, 3]withvalue = 3returns0, the first index. - Returning
-1inside the loop. If the else side of the comparison returns-1, the function gives up after the first element. - Returning the value instead of the index.
return nums[i]returnsvalueitself. - Looping to
nums.countinclusive.0...nums.countwould readnums[nums.count]on a miss and crash.
Testing
nums = [1, 2, 4, 5],value = 4gives2.nums = [3, 3],value = 3gives0.nums = [1],value = 7gives-1.nums = [],value = 1gives-1.
