Problem overview
The method TwoSum(int[] nums, int target) receives an array of integers and a target. It must return the indices of two numbers that add up to target, as an int[] of length 2. There is at most one valid pair, and the same index can't be used twice. If no pair exists, the method returns {-1, -1}.
In the example, nums = {2, 7, 11, 15} and target = 9. The values at indices 0 and 1 are 2 and 7, which sum to 9, so the answer is {0, 1}.
Approach: try every pair
This lesson sets a budget of O(n^2) time and O(1) extra space. That fits the simplest idea: check every pair of positions and stop at the first one that adds up to the target. Faster solutions exist and appear in later lessons, but this brute force is the baseline they improve on.
The pair (i, j) is the same pair as (j, i), so there is no need to check both. Fix the order by letting j always start after i. Then each pair of positions is visited once, and i is never paired with itself, which the problem forbids.
For {2, 7, 11, 15} and target 9, the loops visit (0, 1) first: 2 + 7 is 9, so the method returns immediately with {0, 1}. For the same array and target 100, it visits all six pairs, finds nothing, and returns {-1, -1}.
Step by step
- Loop over the first position. An
int iruns from 0 whilei < nums.Length. Every element can be the first member of the pair. - Loop over the second position. Inside it, an
int jruns fromi + 1whilej < nums.Length. Starting right afteritries each pair once. - Test the pair. If
nums[i] + nums[j] == target, return a newint[]holdingiandj. Returning from inside the loops ends the search at once. - Report failure. After both loops, return
{-1, -1}. This line is reached only when every pair has been tried without a match.
The solution in C#
class Solution {
public int[] TwoSum(int[] nums, int target) {
for (int i = 0; i < nums.Length; ++i) {
for (int j = i + 1; j < nums.Length; ++j) {
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
return new int[]{-1, -1};
}
}
The C# details worth knowing:
- Creating the result.
new int[]{i, j}allocates a new array of length 2 and fills it. C# arrays have a fixed length, so the result is built in one step like this. Length, notlengthorCount. Arrays expose their size as the propertyLength(no parentheses).Countbelongs toList<T>.++iandi++. In a loop header they behave the same, because the value of the expression is not used. Both add 1 after each pass.- Silent overflow.
nums[i] + nums[j]is anintaddition. If the true sum is beyond theintrange, C# wraps around without an error: ifbigholdsint.MaxValue,big + 1evaluates to-2147483648. For very large inputs this could produce a false match. - Printing the result.
Console.WriteLine(result)on an array prints the type name, not the contents. To look at it, usestring.Join(", ", result).
Complexity
Time: O(n^2). The outer loop runs n times, and for position i the inner loop runs n - i - 1 times. The total is (n - 1) + (n - 2) + ... + 1 = n(n - 1) / 2 comparisons in the worst case, which is O(n^2).
Space: O(1). Apart from the two-element result array, the method keeps only i and j. The result has a fixed size and doesn't grow with n.
Edge cases and common mistakes
- Fewer than two elements. An empty array never enters the outer loop, and a one-element array leaves the inner loop empty. Both return
{-1, -1}. - Using one index twice.
{3, 4}with target 6 must return{-1, -1}. Startingjatiwould pair the 3 with itself and wrongly answer{0, 0}. - Equal values.
{3, 3}with target 6 returns{0, 1}. Two equal values at different positions are a valid pair. - Negative numbers and zero. Nothing special is needed:
{-3, 4, 3, 90}with target 0 returns{0, 2}. - Returning values instead of indices. The method returns positions,
{i, j}, notnums[i]andnums[j]. - Forgetting the final return. Without the last line the method doesn't compile, because C# requires every path through a non-void method to return a value.
- Returning
nullor an empty array for "no pair". The problem asks for{-1, -1}.
Testing
{2, 7, 11, 15}, target 9 gives{0, 1}.{3, 3}, target 6 gives{0, 1}.{3, 4}, target 6 gives{-1, -1}.{7, 2}, target 9 gives{0, 1}: the smaller index always comes first.- An empty array with any target gives
{-1, -1}.