167 lines
6.9 KiB
YAML
167 lines
6.9 KiB
YAML
title: Average Value of Even Numbers That Are Divisible by Three
|
|
slug: average-value-of-even-numbers-divisible-by-three
|
|
difficulty: easy
|
|
leetcode_id: 2455
|
|
leetcode_url: https://leetcode.com/problems/average-value-of-even-numbers-that-are-divisible-by-3/
|
|
categories:
|
|
- arrays
|
|
- math
|
|
patterns:
|
|
- slug: prefix-sum
|
|
is_optimal: true
|
|
|
|
function_signature: "def average_value(nums: list[int]) -> int:"
|
|
|
|
test_cases:
|
|
visible:
|
|
- input: { nums: [1, 3, 6, 10, 12, 15] }
|
|
expected: 9
|
|
- input: { nums: [1, 2, 4, 7, 10] }
|
|
expected: 0
|
|
hidden:
|
|
- input: { nums: [6] }
|
|
expected: 6
|
|
- input: { nums: [6, 12, 18] }
|
|
expected: 12
|
|
- input: { nums: [1, 2, 3, 4, 5] }
|
|
expected: 0
|
|
- input: { nums: [6, 6, 6, 6] }
|
|
expected: 6
|
|
- input: { nums: [12, 24, 36, 48, 60] }
|
|
expected: 36
|
|
- input: { nums: [5, 7, 11, 13, 17, 19] }
|
|
expected: 0
|
|
- input: { nums: [6, 12, 1, 2, 3, 18] }
|
|
expected: 12
|
|
|
|
description: |
|
|
Given an integer array `nums` of **positive** integers, return *the average value of all even integers that are divisible by* `3`.
|
|
|
|
Note that the **average** of `n` elements is the **sum** of the `n` elements divided by `n` and **rounded down** to the nearest integer.
|
|
|
|
constraints: |
|
|
- `1 <= nums.length <= 1000`
|
|
- `1 <= nums[i] <= 1000`
|
|
|
|
examples:
|
|
- input: "nums = [1,3,6,10,12,15]"
|
|
output: "9"
|
|
explanation: "6 and 12 are even numbers that are divisible by 3. (6 + 12) / 2 = 9."
|
|
- input: "nums = [1,2,4,7,10]"
|
|
output: "0"
|
|
explanation: "There is no single number that satisfies the requirement, so return 0."
|
|
|
|
explanation:
|
|
intuition: |
|
|
This problem asks us to filter numbers by two conditions and then compute their average.
|
|
|
|
Think of it like sorting through a basket of numbered balls: we only want to pick the balls that satisfy **two criteria simultaneously**. A number must be:
|
|
1. **Even** — divisible by 2
|
|
2. **Divisible by 3**
|
|
|
|
Here's the key insight: a number that is both even (divisible by 2) AND divisible by 3 must be divisible by their least common multiple, which is **6**. So instead of checking two conditions, we can simplify to checking just one: is the number divisible by 6?
|
|
|
|
Once we've identified all qualifying numbers, we sum them up and divide by the count. If no numbers qualify, we return 0.
|
|
|
|
approach: |
|
|
We solve this using a **Single Pass with Running Sum** approach:
|
|
|
|
**Step 1: Initialise tracking variables**
|
|
|
|
- `total`: Set to `0` to accumulate the sum of qualifying numbers
|
|
- `count`: Set to `0` to track how many numbers qualify
|
|
|
|
|
|
|
|
**Step 2: Iterate through the array**
|
|
|
|
- For each number, check if it's divisible by 6 (`num % 6 == 0`)
|
|
- If yes, add it to `total` and increment `count`
|
|
|
|
|
|
|
|
**Step 3: Calculate and return the average**
|
|
|
|
- If `count` is `0`, return `0` (no qualifying numbers)
|
|
- Otherwise, return `total // count` (integer division for rounded-down average)
|
|
|
|
|
|
|
|
This approach processes each element exactly once, making it efficient and straightforward.
|
|
|
|
common_pitfalls:
|
|
- title: Checking Two Conditions Separately
|
|
description: |
|
|
A common approach is to check `num % 2 == 0 and num % 3 == 0` separately. While correct, this is slightly more verbose than necessary.
|
|
|
|
Since even numbers divisible by 3 are exactly the numbers divisible by 6 (LCM of 2 and 3), you can simplify to `num % 6 == 0`.
|
|
wrong_approach: "Check num % 2 == 0 and num % 3 == 0"
|
|
correct_approach: "Check num % 6 == 0"
|
|
|
|
- title: Forgetting the Empty Case
|
|
description: |
|
|
If no numbers in the array satisfy the conditions, dividing by zero will cause an error.
|
|
|
|
For example, with `nums = [1, 2, 4, 7, 10]`, no number is divisible by 6. You must check if `count == 0` before dividing and return `0` in that case.
|
|
wrong_approach: "Return total / count without checking count"
|
|
correct_approach: "Return 0 if count is 0, else total // count"
|
|
|
|
- title: Using Float Division Instead of Integer Division
|
|
description: |
|
|
The problem specifies the average should be **rounded down** to the nearest integer. Using `/` in Python returns a float, while `//` performs integer division (floor division).
|
|
|
|
For `(6 + 12) / 2`, Python's `/` gives `9.0`, but `//` gives `9`. The problem expects an integer result.
|
|
wrong_approach: "total / count (float division)"
|
|
correct_approach: "total // count (integer division)"
|
|
|
|
key_takeaways:
|
|
- "**Simplify conditions with LCM**: When checking divisibility by multiple numbers, consider using their LCM. Even AND divisible by 3 = divisible by 6."
|
|
- "**Handle empty results**: Always check for division by zero when computing averages or ratios."
|
|
- "**Integer vs float division**: Use `//` for floor division when the problem asks for rounded-down results."
|
|
- "**Single pass efficiency**: Accumulating sum and count in one pass is O(n) and avoids storing filtered elements."
|
|
|
|
time_complexity: "O(n). We iterate through the array once, checking each element and updating our running totals."
|
|
space_complexity: "O(1). We only use two variables (`total` and `count`), regardless of input size."
|
|
|
|
solutions:
|
|
- approach_name: Single Pass with Divisibility Check
|
|
is_optimal: true
|
|
code: |
|
|
def average_value(nums: list[int]) -> int:
|
|
# Track sum and count of qualifying numbers
|
|
total = 0
|
|
count = 0
|
|
|
|
for num in nums:
|
|
# Even AND divisible by 3 = divisible by 6
|
|
if num % 6 == 0:
|
|
total += num
|
|
count += 1
|
|
|
|
# Avoid division by zero; return 0 if no qualifying numbers
|
|
return total // count if count > 0 else 0
|
|
explanation: |
|
|
**Time Complexity:** O(n) — Single pass through the array.
|
|
|
|
**Space Complexity:** O(1) — Only two integer variables used.
|
|
|
|
We iterate once, checking each number for divisibility by 6 (the LCM of 2 and 3). This combines the "even" and "divisible by 3" checks into one operation. We accumulate the sum and count, then compute the floor-divided average.
|
|
|
|
- approach_name: Filter and Sum
|
|
is_optimal: false
|
|
code: |
|
|
def average_value(nums: list[int]) -> int:
|
|
# Filter to get all numbers divisible by 6
|
|
qualifying = [num for num in nums if num % 6 == 0]
|
|
|
|
# Return 0 if no qualifying numbers, else compute average
|
|
if not qualifying:
|
|
return 0
|
|
return sum(qualifying) // len(qualifying)
|
|
explanation: |
|
|
**Time Complexity:** O(n) — Two passes: one for filtering, one for summing.
|
|
|
|
**Space Complexity:** O(k) — Where k is the number of qualifying elements.
|
|
|
|
This approach is more readable by separating the filtering and averaging steps. However, it uses extra space to store the filtered list. For this problem's constraints (n <= 1000), the difference is negligible, but the single-pass approach is more memory-efficient.
|