Facebook Pixel

3371. Identify the Largest Outlier in an Array

MediumArrayHash TableCountingEnumeration
Leetcode Link

Problem Description

You are given an integer array nums containing n elements. Among these elements:

  • Exactly n - 2 elements are special numbers
  • One element is the sum of all the special numbers
  • One element is an outlier

An outlier is defined as a number that is:

  • NOT one of the original special numbers
  • NOT the sum of the special numbers

Important constraints:

  • All elements (special numbers, sum element, and outlier) must have distinct indices in the array
  • However, they may have the same values

Your task is to find and return the largest possible outlier in nums.

For example, if nums = [2, 3, 5, 10, 100], the special numbers could be 2, 3, 5, their sum would be 10, and the outlier would be 100. But we need to check all possible combinations to find the largest valid outlier.

The solution works by:

  1. For each element x in the array, consider it as a potential outlier
  2. Calculate the remaining sum t = total_sum - x
  3. Check if t is even (since t = sum_element + special_numbers_sum, and sum_element = special_numbers_sum, so t must be even)
  4. Check if t/2 exists in the array (this would be the sum of special numbers)
  5. Verify that the configuration is valid (either x ≠ t/2 or x appears more than once)
  6. Track the maximum valid outlier found
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Let's think about the structure of this problem. We have n elements where n-2 are special numbers, one is their sum, and one is the outlier.

If we denote the special numbers as s₁, s₂, ..., s_{n-2}, then:

  • The sum element equals s₁ + s₂ + ... + s_{n-2}
  • There's one outlier that doesn't relate to the special numbers

The key insight is that if we remove the outlier from the array, what remains are the special numbers and their sum. This means:

  • Total of remaining elements = special numbers + sum of special numbers
  • Since the sum element equals the sum of special numbers, we have:
  • Total of remaining elements = special numbers + special numbers = 2 × (sum of special numbers)

This tells us that after removing the outlier, the remaining sum must be even!

So for each element x that we consider as a potential outlier:

  1. Calculate the remaining sum: t = total_sum - x
  2. If t is odd, then x cannot be the outlier
  3. If t is even, then t/2 should be the sum of special numbers
  4. Check if t/2 actually exists in our array (it must be present as the sum element)

There's one edge case: what if the outlier value equals t/2? This creates ambiguity since the same value appears as both the outlier and the sum element. This is only valid if that value appears at least twice in the array (at different indices).

By checking each element as a potential outlier and validating these conditions, we can find all valid outliers and return the largest one.

Solution Approach

We use a hash table to track element frequencies and systematically check each element as a potential outlier.

Step 1: Initialize Data Structures

  • Calculate the total sum s of all elements in nums
  • Create a frequency counter cnt to store how many times each element appears
  • Initialize the answer ans to negative infinity

Step 2: Enumerate Each Potential Outlier For each unique element x in the counter with frequency v:

  1. Calculate the remaining sum after removing x: t = s - x
  2. Check if t is even (if not, skip this x as it cannot be an outlier)
  3. Calculate what the sum of special numbers should be: sum_of_specials = t // 2
  4. Verify if sum_of_specials exists in the array by checking cnt[t // 2] > 0

Step 3: Handle Edge Cases When validating x as an outlier, we need to ensure:

  • If x == t // 2 (outlier value equals the sum value), then x must appear at least twice (v > 1) to have distinct indices for both roles
  • If x != t // 2, then x is a valid outlier as long as t // 2 exists in the array

Step 4: Update Maximum If all conditions are met, update ans = max(ans, x) to track the largest valid outlier.

The algorithm runs in O(n) time where n is the length of the array, as we iterate through the array once to build the counter and then iterate through unique elements once more. The space complexity is also O(n) for storing the counter.

The key insight is recognizing that total_sum - outlier = 2 × sum_of_special_numbers, which allows us to efficiently validate each potential outlier without explicitly finding all special numbers.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [2, 3, 5, 10, 100].

Step 1: Initialize

  • Total sum s = 2 + 3 + 5 + 10 + 100 = 120
  • Frequency counter: cnt = {2: 1, 3: 1, 5: 1, 10: 1, 100: 1}
  • Answer ans = -infinity

Step 2: Check each element as potential outlier

Try x = 2 as outlier:

  • Remaining sum: t = 120 - 2 = 118
  • Is t even? Yes ✓
  • Sum of specials should be: t/2 = 118/2 = 59
  • Does 59 exist in array? Check cnt[59] > 0 → No ✗
  • Cannot be outlier

Try x = 3 as outlier:

  • Remaining sum: t = 120 - 3 = 117
  • Is t even? No ✗
  • Cannot be outlier

Try x = 5 as outlier:

  • Remaining sum: t = 120 - 5 = 115
  • Is t even? No ✗
  • Cannot be outlier

Try x = 10 as outlier:

  • Remaining sum: t = 120 - 10 = 110
  • Is t even? Yes ✓
  • Sum of specials should be: t/2 = 110/2 = 55
  • Does 55 exist in array? Check cnt[55] > 0 → No ✗
  • Cannot be outlier

Try x = 100 as outlier:

  • Remaining sum: t = 120 - 100 = 20
  • Is t even? Yes ✓
  • Sum of specials should be: t/2 = 20/2 = 10
  • Does 10 exist in array? Check cnt[10] > 0 → Yes ✓
  • Is x = 100 different from t/2 = 10? Yes ✓
  • Valid outlier! Update ans = max(-infinity, 100) = 100

This means: Special numbers are 2, 3, 5 (sum = 10), sum element is 10, and outlier is 100.

Step 3: Continue checking remaining possibilities

We could also check if other elements could be outliers with different special number combinations. For instance:

Try x = 5 again with different perspective: Actually, let's verify if 2 could be the outlier in another configuration:

  • If 2 is outlier, remaining sum = 118
  • We need 59 as sum element (not in array)

After checking all possibilities, the maximum valid outlier is 100.

Solution Implementation

1class Solution:
2    def getLargestOutlier(self, nums: List[int]) -> int:
3        # Calculate the total sum of all numbers
4        total_sum = sum(nums)
5      
6        # Count frequency of each number in the array
7        frequency_map = Counter(nums)
8      
9        # Initialize result to negative infinity
10        max_outlier = -inf
11      
12        # Try each unique number as a potential outlier
13        for potential_outlier, outlier_frequency in frequency_map.items():
14            # Calculate what the sum of remaining elements would be
15            # if potential_outlier is removed from total
16            remaining_sum = total_sum - potential_outlier
17          
18            # For potential_outlier to be valid:
19            # remaining_sum should equal (sum_of_array_except_one_element) + that_one_element
20            # So: remaining_sum = 2 * that_one_element
21            # Therefore: that_one_element = remaining_sum / 2
22          
23            # Check if remaining_sum is even (divisible by 2)
24            if remaining_sum % 2 != 0:
25                continue
26          
27            # Calculate the element that should be excluded from sum
28            excluded_element = remaining_sum // 2
29          
30            # Check if this excluded element exists in the array
31            if frequency_map[excluded_element] == 0:
32                continue
33          
34            # Validate: if outlier and excluded element are the same,
35            # we need at least 2 occurrences (one as outlier, one as excluded)
36            if potential_outlier != excluded_element or outlier_frequency > 1:
37                max_outlier = max(max_outlier, potential_outlier)
38      
39        return max_outlier
40
1class Solution {
2    public int getLargestOutlier(int[] nums) {
3        // Calculate total sum and count frequency of each number
4        int totalSum = 0;
5        Map<Integer, Integer> frequencyMap = new HashMap<>();
6      
7        for (int number : nums) {
8            totalSum += number;
9            // Increment frequency count for this number
10            frequencyMap.merge(number, 1, Integer::sum);
11        }
12      
13        // Initialize result with minimum possible value
14        int largestOutlier = Integer.MIN_VALUE;
15      
16        // Try each unique number as a potential outlier
17        for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
18            int potentialOutlier = entry.getKey();
19            int frequency = entry.getValue();
20          
21            // Calculate what the sum of remaining numbers would be
22            int remainingSum = totalSum - potentialOutlier;
23          
24            // Check if this configuration is valid:
25            // The remaining sum should be even (since one number equals sum of others)
26            // And the sum value (remainingSum/2) must exist in the array
27            if (remainingSum % 2 != 0 || !frequencyMap.containsKey(remainingSum / 2)) {
28                continue;
29            }
30          
31            int sumValue = remainingSum / 2;
32          
33            // Validate that we have enough occurrences:
34            // If outlier equals the sum value, we need at least 2 occurrences
35            // Otherwise, both outlier and sum value can coexist
36            if (potentialOutlier != sumValue || frequency > 1) {
37                largestOutlier = Math.max(largestOutlier, potentialOutlier);
38            }
39        }
40      
41        return largestOutlier;
42    }
43}
44
1class Solution {
2public:
3    int getLargestOutlier(vector<int>& nums) {
4        // Calculate total sum and count frequency of each element
5        int totalSum = 0;
6        unordered_map<int, int> frequencyMap;
7      
8        for (int num : nums) {
9            totalSum += num;
10            frequencyMap[num]++;
11        }
12      
13        int largestOutlier = INT_MIN;
14      
15        // Try each unique number as a potential outlier
16        for (auto [outlierCandidate, frequency] : frequencyMap) {
17            // Calculate remaining sum after removing the outlier candidate
18            int remainingSum = totalSum - outlierCandidate;
19          
20            // Check if remaining sum is even (must be divisible by 2)
21            if (remainingSum % 2 != 0) {
22                continue;
23            }
24          
25            // Check if half of the remaining sum exists in the array
26            int targetValue = remainingSum / 2;
27            if (!frequencyMap.contains(targetValue)) {
28                continue;
29            }
30          
31            // Validate: if outlier candidate equals target value,
32            // we need at least 2 occurrences (one for outlier, one for target)
33            if (outlierCandidate == targetValue && frequency <= 1) {
34                continue;
35            }
36          
37            // Update maximum outlier value
38            largestOutlier = max(largestOutlier, outlierCandidate);
39        }
40      
41        return largestOutlier;
42    }
43};
44
1/**
2 * Finds the largest outlier in an array where the outlier is defined as:
3 * a number that is neither part of a pair (num, sum) where one element
4 * equals the sum of another element in the array
5 * 
6 * @param nums - Array of numbers to process
7 * @returns The largest outlier value
8 */
9function getLargestOutlier(nums: number[]): number {
10    // Calculate total sum of all numbers
11    let totalSum: number = 0;
12    // Count frequency of each number in the array
13    const frequencyMap: Record<number, number> = {};
14  
15    for (const num of nums) {
16        totalSum += num;
17        frequencyMap[num] = (frequencyMap[num] || 0) + 1;
18    }
19  
20    // Track the maximum outlier found
21    let maxOutlier: number = -Infinity;
22  
23    // Check each unique number as a potential outlier
24    for (const [numStr, frequency] of Object.entries(frequencyMap)) {
25        const currentNum: number = Number(numStr);
26        // Calculate remaining sum if current number is the outlier
27        const remainingSum: number = totalSum - currentNum;
28      
29        // Skip if remaining sum is odd (can't be split into equal halves)
30        // or if half of remaining sum doesn't exist in the array
31        const halfSum: number = Math.floor(remainingSum / 2);
32        if (remainingSum % 2 !== 0 || !frequencyMap.hasOwnProperty(halfSum)) {
33            continue;
34        }
35      
36        // Valid outlier if:
37        // 1. Current number is different from half sum, OR
38        // 2. Current number equals half sum but appears more than once
39        if (currentNum !== halfSum || frequency > 1) {
40            maxOutlier = Math.max(maxOutlier, currentNum);
41        }
42    }
43  
44    return maxOutlier;
45}
46

Time and Space Complexity

The time complexity is O(n), where n is the length of the array nums. This is because:

  • Computing the sum of nums takes O(n) time
  • Creating the Counter (frequency map) requires iterating through all elements once, which takes O(n) time
  • The main loop iterates through the Counter's items, which in the worst case contains n unique elements, taking O(n) time
  • Each operation inside the loop (arithmetic operations, dictionary lookups, and comparisons) takes O(1) time

The space complexity is O(n), where n is the length of the array nums. This is because:

  • The Counter cnt stores the frequency of each unique element in nums, which in the worst case (all elements are unique) requires O(n) space
  • Other variables (s, ans, x, v, t) use constant space O(1)

Learn more about how to find time and space complexity quickly.

Common Pitfalls

Pitfall 1: Confusing the Problem Structure

The Mistake: Many people initially misunderstand what "sum element" represents. They think it's the sum of ALL elements including the outlier, when it's actually the sum of only the special numbers.

Why It Happens: The problem states there are n-2 special numbers, 1 sum element, and 1 outlier. It's easy to misinterpret that the sum element should be the sum of everything.

Example of Wrong Thinking:

# WRONG: Trying to find sum_element = sum(all elements)
for potential_outlier in nums:
    if sum(nums) - potential_outlier in nums:  # This is incorrect logic
        # ...

Correct Understanding: The array structure is:

  • n-2 special numbers: [a₁, a₂, ..., aₙ₋₂]
  • 1 sum element: S = a₁ + a₂ + ... + aₙ₋₂
  • 1 outlier: X (unrelated to special numbers or their sum)

Pitfall 2: Not Handling Duplicate Values Correctly

The Mistake: Forgetting that when the outlier value equals the sum value (x == t//2), we need at least 2 occurrences of that value in the array.

Example of Wrong Code:

# WRONG: Not checking frequency when values are equal
if remaining_sum % 2 == 0 and remaining_sum // 2 in frequency_map:
    max_outlier = max(max_outlier, potential_outlier)  # Missing frequency check!

Why It Fails: Consider nums = [1, 1, 1, 3]. If we try 1 as outlier:

  • remaining_sum = 5 - 1 = 4
  • sum_of_specials = 4 // 2 = 2
  • But 2 doesn't exist in array, so 1 cannot be outlier

However, if we try 3 as outlier:

  • remaining_sum = 5 - 3 = 2
  • sum_of_specials = 2 // 2 = 1
  • 1 exists in array, and since 3 ≠ 1, this works!

Correct Approach:

if potential_outlier != excluded_element or outlier_frequency > 1:
    max_outlier = max(max_outlier, potential_outlier)

Pitfall 3: Integer Division vs Float Division

The Mistake: Using float division (/) instead of integer division (//) when checking if a value exists in the frequency map.

Wrong Code:

# WRONG: Using float division
excluded_element = remaining_sum / 2  # This creates a float!
if frequency_map[excluded_element] > 0:  # KeyError if excluded_element is 2.0

Why It Fails: Python's Counter keys are the actual values from the array (integers). Using float division creates float keys (like 2.0 instead of 2), which won't match the integer keys in the frequency map.

Correct Code:

excluded_element = remaining_sum // 2  # Integer division
if frequency_map[excluded_element] > 0:  # Works correctly

Solution Summary

To avoid these pitfalls:

  1. Understand the mathematical relationship: total_sum - outlier = 2 × sum_of_specials
  2. Always check frequencies: When outlier value equals sum value, verify sufficient occurrences exist
  3. Use integer arithmetic: Stick to integer division when working with integer arrays
  4. Test edge cases: Arrays with duplicate values, negative numbers, and where multiple valid configurations exist
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which of these pictures shows the visit order of a depth-first search?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More