Problem overview
The method Contains(int[] nums, int value) returns true if value appears anywhere in nums, and false otherwise. The lesson asks you to write the search yourself rather than call a ready-made method such as Array.IndexOf or LINQ's Contains.
For nums = {1, 2, 4, 5} and value = 4 the answer is true, because 4 is the third element. For nums = {-1, 2, -4, 0, 10} and value = 7 the answer is false: no element equals 7.
Approach: a linear search
The array is not sorted, so there is no shortcut: the only way to know that a value is missing is to look at every element. The method visits the elements one at a time and compares each with value.
- If an element equals
value, the answer istrueand there is no reason to look further. - If the loop ends without a match, every element has been seen and none was equal, so the answer is
false.
This is called a linear search. The important point is that false may only be returned after the loop. Returning false for the first element that doesn't match would be wrong, because the next element might match.
Step by step
- Loop with
foreach.foreach (int val in nums)hands each element to the body asval, in order, with no index to manage. - Compare inside the loop. When
val == value, returntrueat once. Areturnends the whole method, so the remaining elements are not checked. - Return
falseafter the loop. The only way to reach this line is for the loop to have finished without a return, which means there was no match. Noelseis needed.
The solution in C#
class Solution {
public bool Contains(int[] nums, int value) {
foreach (int val in nums) {
if (val == value) {
return true;
}
}
return false;
}
}
C# details worth noting:
- The return type is
bool, with the literalstrueandfalsein lowercase. The Java-stylebooleanand Python-styleTruedo not exist in C#. - Every path must return. The compiler rejects a method that can end without a value. The final
return false;covers the path where the loop finishes. - Comparing
intvalues with==compares the numbers themselves. That is not the case for every type, but it is for all the numeric types. - An empty array works with no special code: the loop body never runs, and the method returns
false.
The same search with an index
A for loop over indexes does the same job and is the version to reach for when you also need the position of the match:
for (int i = 0; i < nums.Length; i++) {
if (nums[i] == value) {
return true;
}
}
return false;
Arrays in C# report their size through the Length property, with no parentheses. Because the lesson only asks whether the value exists, foreach is shorter and removes the chance of an off-by-one mistake in the loop bounds.
Complexity
Time: O(n). In the worst case, the value is last or absent, and the loop does one comparison per element. In the best case the value is first and the loop stops after one comparison.
Space: O(1). Only the loop variable is used, however long the array is.
Edge cases and common mistakes
- Returning
falseinside the loop. With anelse { return false; }next to theif, the method answers after looking only at the first element.Contains({1, 2, 4, 5}, 4)would wrongly returnfalse. - Missing the final return. Without it, the code does not compile.
- Duplicates. If the value appears several times, the method stops at the first one, which is all the question needs.
- Negative numbers and zero need no special handling;
==treats them like any other value. - Assigning with
=instead of comparing with==. In C#,if (val = value)does not compile, because anintis not abool.
Testing
{1, 2, 4, 5},4givestrue.{-1, 2, -4, 0, 10},7givesfalse.{},3givesfalse.{5},5givestrue.