Facebook Pixel

3452. Sum of Good Numbers

Problem Description

You are given an array of integers nums and an integer k. An element nums[i] is considered good if it satisfies the following conditions:

  • If the index i - k exists (meaning i >= k), then nums[i] must be strictly greater than nums[i - k]
  • If the index i + k exists (meaning i + k < len(nums)), then nums[i] must be strictly greater than nums[i + k]
  • If neither of these indices exists, nums[i] is automatically considered good

In other words, a number is good if it's strictly greater than the elements that are exactly k positions away from it (both before and after), when such positions exist in the array.

Your task is to find and return the sum of all the good elements in the array.

For example, if nums = [3, 5, 1, 6, 2] and k = 2:

  • nums[0] = 3: Only needs to be greater than nums[2] = 1 (since i - k doesn't exist). Since 3 > 1, it's good.
  • nums[1] = 5: Only needs to be greater than nums[3] = 6 (since i - k doesn't exist). Since 5 ≤ 6, it's not good.
  • nums[2] = 1: Needs to be greater than both nums[0] = 3 and nums[4] = 2. Since 1 ≤ 3, it's not good.
  • nums[3] = 6: Only needs to be greater than nums[1] = 5 (since i + k doesn't exist). Since 6 > 5, it's good.
  • nums[4] = 2: Only needs to be greater than nums[2] = 1 (since i + k doesn't exist). Since 2 > 1, it's good.

The sum of good elements would be 3 + 6 + 2 = 11.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The problem asks us to identify "good" numbers based on a simple comparison rule: each number must be strictly greater than its neighbors that are exactly k positions away. This naturally leads to a direct checking approach.

The key insight is that we need to check each element against at most two other elements - one that's k positions before it and one that's k positions after it. However, we need to be careful about boundary conditions:

  • For elements near the beginning of the array (where i < k), there's no element k positions before them
  • For elements near the end of the array (where i + k >= len(nums)), there's no element k positions after them

When these boundary positions don't exist, we simply don't need to check them - the element automatically passes that part of the condition.

The solution uses a clever optimization: instead of checking if an element is "good", we check if it's "not good". An element is not good if:

  1. There exists an element k positions before it AND the current element is not strictly greater than it (i.e., nums[i] <= nums[i-k])
  2. OR there exists an element k positions after it AND the current element is not strictly greater than it (i.e., nums[i] <= nums[i+k])

If either of these conditions is true, we skip the element using continue. Otherwise, we add it to our sum.

This reverse logic (checking for "not good" rather than "good") makes the code cleaner because we can use early exit conditions with continue statements, avoiding nested if-statements and making the logic more straightforward to follow.

Solution Approach

The implementation uses a straightforward traversal approach to solve this problem. Let's walk through the solution step by step:

  1. Initialize the answer variable: We start with ans = 0 to accumulate the sum of all good numbers.

  2. Traverse the array: We use enumerate() to iterate through the array, getting both the index i and the value x at each position.

  3. Check conditions for each element: For each element nums[i], we check if it fails to be a "good" number:

    • First condition check: if i >= k and x <= nums[i - k]:
      • We first verify that index i - k exists (by checking i >= k)
      • If it exists and nums[i] is not strictly greater than nums[i - k] (meaning x <= nums[i - k]), then this element is not good
      • We use continue to skip this element and move to the next one
    • Second condition check: if i + k < len(nums) and x <= nums[i + k]:
      • We verify that index i + k exists (by checking i + k < len(nums))
      • If it exists and nums[i] is not strictly greater than nums[i + k] (meaning x <= nums[i + k]), then this element is not good
      • We use continue to skip this element
  4. Add good numbers to the sum: If an element passes both checks (doesn't hit either continue statement), it means:

    • Either the comparison indices don't exist (boundary cases)
    • OR the element is strictly greater than the elements at those indices

    In both cases, the element is "good", so we add it to our answer: ans += x

  5. Return the result: After traversing the entire array, we return the accumulated sum.

The time complexity is O(n) where n is the length of the array, as we visit each element exactly once. The space complexity is O(1) as we only use a constant amount of extra space for the answer variable.

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 = [7, 2, 9, 4, 8] and k = 2:

Initial setup: ans = 0

Iteration 1: i = 0, x = 7

  • Check i >= k: 0 >= 2? No, skip first condition
  • Check i + k < len(nums): 0 + 2 < 5? Yes, check if 7 <= nums[2]
    • nums[2] = 9, so 7 <= 9? Yes, this is true
    • Element is NOT good, continue to next iteration
  • ans remains 0

Iteration 2: i = 1, x = 2

  • Check i >= k: 1 >= 2? No, skip first condition
  • Check i + k < len(nums): 1 + 2 < 5? Yes, check if 2 <= nums[3]
    • nums[3] = 4, so 2 <= 4? Yes, this is true
    • Element is NOT good, continue to next iteration
  • ans remains 0

Iteration 3: i = 2, x = 9

  • Check i >= k: 2 >= 2? Yes, check if 9 <= nums[0]
    • nums[0] = 7, so 9 <= 7? No, this is false, condition passes
  • Check i + k < len(nums): 2 + 2 < 5? Yes, check if 9 <= nums[4]
    • nums[4] = 8, so 9 <= 8? No, this is false, condition passes
  • Both conditions pass, element is GOOD!
  • ans = 0 + 9 = 9

Iteration 4: i = 3, x = 4

  • Check i >= k: 3 >= 2? Yes, check if 4 <= nums[1]
    • nums[1] = 2, so 4 <= 2? No, this is false, condition passes
  • Check i + k < len(nums): 3 + 2 < 5? No, skip second condition
  • Element is GOOD!
  • ans = 9 + 4 = 13

Iteration 5: i = 4, x = 8

  • Check i >= k: 4 >= 2? Yes, check if 8 <= nums[2]
    • nums[2] = 9, so 8 <= 9? Yes, this is true
    • Element is NOT good, continue
  • ans remains 13

Final Result: The sum of good elements is 13 (elements 9 and 4 are good).

Solution Implementation

1class Solution:
2    def sumOfGoodNumbers(self, nums: List[int], k: int) -> int:
3        """
4        Calculate the sum of 'good' numbers in the array.
5        A number is 'good' if it's greater than all its k-distance neighbors that exist.
6      
7        Args:
8            nums: List of integers
9            k: Distance parameter for checking neighbors
10          
11        Returns:
12            Sum of all good numbers in the array
13        """
14        total_sum = 0
15      
16        # Iterate through each element with its index
17        for index, current_value in enumerate(nums):
18            # Check left k-distance neighbor if it exists
19            # Skip this element if it's not greater than left neighbor
20            if index >= k and current_value <= nums[index - k]:
21                continue
22              
23            # Check right k-distance neighbor if it exists  
24            # Skip this element if it's not greater than right neighbor
25            if index + k < len(nums) and current_value <= nums[index + k]:
26                continue
27              
28            # Current element is greater than all existing k-distance neighbors
29            # Add it to the sum
30            total_sum += current_value
31          
32        return total_sum
33
1class Solution {
2    /**
3     * Calculates the sum of "good" numbers in the array.
4     * A number at index i is considered "good" if:
5     * - It is greater than the element k positions before it (if exists)
6     * - It is greater than the element k positions after it (if exists)
7     * 
8     * @param nums the input array of integers
9     * @param k the distance to check for comparison
10     * @return the sum of all good numbers
11     */
12    public int sumOfGoodNumbers(int[] nums, int k) {
13        int sum = 0;
14        int arrayLength = nums.length;
15      
16        // Iterate through each element in the array
17        for (int i = 0; i < arrayLength; i++) {
18            // Check if current element is not greater than element k positions before
19            if (i >= k && nums[i] <= nums[i - k]) {
20                continue; // Skip this element as it's not a good number
21            }
22          
23            // Check if current element is not greater than element k positions after
24            if (i + k < arrayLength && nums[i] <= nums[i + k]) {
25                continue; // Skip this element as it's not a good number
26            }
27          
28            // Current element is a good number, add it to the sum
29            sum += nums[i];
30        }
31      
32        return sum;
33    }
34}
35
1class Solution {
2public:
3    int sumOfGoodNumbers(vector<int>& nums, int k) {
4        int sum = 0;
5        int n = nums.size();
6      
7        // Iterate through each element in the array
8        for (int i = 0; i < n; ++i) {
9            // Check if current element is NOT a "good number"
10            // A number is NOT good if:
11          
12            // 1. There exists an element k positions before that is >= current element
13            if (i >= k && nums[i] <= nums[i - k]) {
14                continue; // Skip this element as it's not a good number
15            }
16          
17            // 2. There exists an element k positions after that is >= current element
18            if (i + k < n && nums[i] <= nums[i + k]) {
19                continue; // Skip this element as it's not a good number
20            }
21          
22            // If we reach here, nums[i] is a "good number"
23            // (greater than elements at distance k in both directions, if they exist)
24            sum += nums[i];
25        }
26      
27        return sum;
28    }
29};
30
1/**
2 * Calculates the sum of "good" numbers in an array.
3 * A number at index i is considered "good" if:
4 * - It is greater than the number k positions before it (if exists)
5 * - It is greater than the number k positions after it (if exists)
6 * 
7 * @param nums - The input array of numbers
8 * @param k - The distance to check for neighboring elements
9 * @returns The sum of all good numbers
10 */
11function sumOfGoodNumbers(nums: number[], k: number): number {
12    const arrayLength: number = nums.length;
13    let totalSum: number = 0;
14  
15    // Iterate through each element in the array
16    for (let currentIndex: number = 0; currentIndex < arrayLength; currentIndex++) {
17        // Check if current element is not greater than element k positions before
18        if (currentIndex >= k && nums[currentIndex] <= nums[currentIndex - k]) {
19            continue;
20        }
21      
22        // Check if current element is not greater than element k positions after
23        if (currentIndex + k < arrayLength && nums[currentIndex] <= nums[currentIndex + k]) {
24            continue;
25        }
26      
27        // If both conditions pass, add current element to sum
28        totalSum += nums[currentIndex];
29    }
30  
31    return totalSum;
32}
33

Time and Space Complexity

The time complexity is O(n), where n is the length of the array nums. The algorithm iterates through the array exactly once using a single for loop with enumerate(nums). For each element at index i, it performs at most two constant-time comparisons: checking if i >= k and comparing x with nums[i - k], and checking if i + k < len(nums) and comparing x with nums[i + k]. Since these operations take O(1) time and are performed for each of the n elements, the overall time complexity is O(n).

The space complexity is O(1). The algorithm only uses a fixed amount of extra space for variables ans, i, and x, regardless of the input size. No additional data structures that grow with the input size are created, making the space complexity constant.

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

Common Pitfalls

1. Confusing Index Distance with Adjacent Elements

A frequent mistake is thinking that k refers to adjacent elements rather than elements exactly k positions away. For instance, with k=2, you need to check positions i-2 and i+2, NOT positions i-1 and i+1.

Incorrect implementation:

# Wrong: Checking all elements within k distance
for j in range(max(0, i-k), min(len(nums), i+k+1)):
    if j != i and nums[i] <= nums[j]:
        # This checks too many elements!

Correct approach:

# Right: Only check elements at exactly k distance
if i >= k and nums[i] <= nums[i-k]:
    continue
if i + k < len(nums) and nums[i] <= nums[i+k]:
    continue

2. Using Non-Strict Comparison

The problem requires strictly greater comparison (>), not greater-than-or-equal (>=). Using the wrong comparison operator will include elements that should be excluded.

Incorrect:

if i >= k and current_value < nums[i - k]:  # Wrong: should be <=
    continue

Correct:

if i >= k and current_value <= nums[i - k]:  # Correct: element must be strictly greater
    continue

3. Incorrect Boundary Checking Logic

A subtle error is misunderstanding when an element is automatically "good". Elements are good by default when comparison indices don't exist, not when they fail the comparison.

Incorrect logic:

# Wrong: Treating out-of-bounds as automatic failure
is_good = True
if i >= k:
    is_good = nums[i] > nums[i-k]
if i + k < len(nums):
    is_good = is_good and nums[i] > nums[i+k]
# This fails when only one boundary exists

Correct logic:

# Right: Only fail when index exists AND comparison fails
is_good = True
if i >= k and nums[i] <= nums[i-k]:
    is_good = False
if i + k < len(nums) and nums[i] <= nums[i+k]:
    is_good = False

4. Off-by-One Errors in Index Validation

Be careful with the boundary conditions. The left boundary check should be i >= k (not i > k), and the right boundary should be i + k < len(nums) (not i + k <= len(nums)).

Example to verify boundaries:

  • For an array of length 5 with k=2:
    • At index 0: Check index 2 (exists) but not index -2
    • At index 2: Check indices 0 and 4 (both exist)
    • At index 4: Check index 2 (exists) but not index 6
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

What is the best way of checking if an element exists in a sorted array once in terms of time complexity? Select the best that applies.


Recommended Readings

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

Load More