Array Contains - Time Complexity: O(n) - Java


Given an array of integers nums and another integer value, check if value occurs in nums.

If the value occurs in nums, return true; otherwise return false.


Examples:

contains([1, 2, 4, 5], 4) -> true

contains([-1, 2, -4, 0, 10], 7) -> false

Note:

Do not use builtin functions such as includes(), it would defy the whole purpose of the challenge.

Understanding the Problem

The core challenge of this problem is to determine if a given integer exists within an array of integers. This is a fundamental problem in computer science with applications in searching algorithms, data validation, and more. A common pitfall is to use built-in functions that simplify the task, but the challenge here is to implement the search manually.

Approach

To solve this problem, we can use a simple linear search algorithm. The idea is to iterate through each element of the array and check if it matches the given value. This approach is straightforward and ensures that we check every possible position in the array.

Naive Solution

The naive solution involves iterating through the array and checking each element one by one. This solution is not necessarily inefficient for this problem, as it has a time complexity of O(n), where n is the number of elements in the array. However, it is important to understand its limitations in terms of performance for very large arrays.

Optimized Solution

For this specific problem, the naive solution is already optimal in terms of time complexity. However, if the array were sorted, we could use a binary search algorithm to improve the time complexity to O(log n). Since the problem does not specify that the array is sorted, we will stick with the linear search approach.

Algorithm

Here is a step-by-step breakdown of the linear search algorithm:

  1. Initialize a loop to iterate through each element of the array.
  2. For each element, check if it matches the given value.
  3. If a match is found, return true.
  4. If the loop completes without finding a match, return false.

Code Implementation

public class ArrayContains {
    // Method to check if the array contains the given value
    public static boolean contains(int[] nums, int value) {
        // Iterate through each element in the array
        for (int num : nums) {
            // Check if the current element matches the given value
            if (num == value) {
                return true; // Value found, return true
            }
        }
        return false; // Value not found, return false
    }

    // Main method to test the contains method
    public static void main(String[] args) {
        int[] nums1 = {1, 2, 4, 5};
        int value1 = 4;
        System.out.println(contains(nums1, value1)); // Output: true

        int[] nums2 = {-1, 2, -4, 0, 10};
        int value2 = 7;
        System.out.println(contains(nums2, value2)); // Output: false
    }
}

Complexity Analysis

The time complexity of the linear search algorithm is O(n), where n is the number of elements in the array. This is because, in the worst case, we may need to check every element in the array. The space complexity is O(1) since we are not using any additional space that scales with the input size.

Edge Cases

Potential edge cases include:

  • An empty array: The function should return false.
  • An array with one element: The function should correctly identify if the single element matches the value.
  • Arrays with negative numbers and zeros: The function should handle these correctly.

Examples:

contains([], 1) -> false
contains([1], 1) -> true
contains([-1, 0, 1], 0) -> true

Testing

To test the solution comprehensively, consider the following test cases:

  • Simple cases with small arrays.
  • Edge cases such as empty arrays and single-element arrays.
  • Arrays with negative numbers and zeros.
  • Large arrays to test performance.

Using a testing framework like JUnit can help automate and manage these tests effectively.

Thinking and Problem-Solving Tips

When approaching such problems, it is important to:

  • Understand the problem requirements and constraints.
  • Start with a simple, brute-force solution to ensure correctness.
  • Think about potential optimizations and their trade-offs.
  • Consider edge cases and how your solution handles them.
  • Practice similar problems to improve problem-solving skills.

Conclusion

In this blog post, we discussed how to determine if an array contains a specific value using a linear search algorithm. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for developing strong problem-solving skills in computer science.

Additional Resources

For further reading and practice, consider the following resources: