You are given a closed integer interval [l, r]
and an integer array banned
.
Return the maximum number of integers you can choose from the interval [l, r]
that are not in the banned
array and have a sum less than or equal to maxSum
.
Example 1:
Input: banned = [1,4,2,3], n = 4, maxSum = 6 Output: 2 Explanation: You can choose the integers [5,6]. Note that the integers 1, 2, 3, and 4 are banned, so you cannot choose them.
Example 2:
Input: banned = [1,2,3,4,5,6,7], n = 8, maxSum = 1 Output: 0 Explanation: You cannot choose any integer from the interval [1,8] since each integer is banned.
Example 3:
Input: banned = [11], n = 7, maxSum = 50 Output: 7 Explanation: You can choose the integers [1,2,3,4,5,6,7]. Note that the integer 11 is banned, so you cannot choose it.
Constraints:
1 <= banned.length <= 104
1 <= banned[i] <= 105
1 <= n <= 105
1 <= maxSum <= 109
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem involves systematically checking every possible combination of numbers within the given range. We essentially try every subset of numbers to see if it satisfies our constraints. This approach guarantees finding the optimal solution but is highly inefficient.
Here's how the algorithm would work step-by-step:
def max_number_of_integers_brute_force(
number_range_start, number_range_end, forbidden_numbers, maximum_sum
):
maximum_integers_to_choose = 0
for i in range(1 << (number_range_end - number_range_start + 1)):
current_subset = []
current_sum = 0
number_count = 0
for j in range(number_range_end - number_range_start + 1):
if (i >> j) & 1:
current_number = number_range_start + j
# Check if the current number is in the forbidden list.
if current_number in forbidden_numbers:
current_subset = []
current_sum = 0
number_count = 0
break
current_subset.append(current_number)
current_sum += current_number
number_count += 1
# Prune the search if sum is over the limit
if current_sum > maximum_sum:
continue
maximum_integers_to_choose = max(
maximum_integers_to_choose, number_count
)
return maximum_integers_to_choose
The goal is to pick the most numbers possible from a range, given some numbers we're not allowed to pick and a limit on the sum of our chosen numbers. We use a greedy approach, trying to pick the smallest available numbers first because they take up less of our limited sum, maximizing how many we can ultimately select.
Here's how the algorithm would work step-by-step:
def max_number_of_integers(number_of_integers, banned_numbers, maximum_sum):
available_numbers = set(range(1, number_of_integers + 1)) - set(banned_numbers)
chosen_integers_count = 0
current_sum = 0
# Greedily pick the smallest available numbers.
for number in sorted(available_numbers):
if current_sum + number <= maximum_sum:
current_sum += number
chosen_integers_count += 1
else:
# Stop if adding the next number exceeds the limit.
break
return chosen_integers_count
Case | How to Handle |
---|---|
banned is null or empty | If banned is null or empty, proceed without filtering any numbers from the range 1 to maxSum. |
maxSum is zero | If maxSum is zero, no integers can be chosen, so return 0. |
n is zero | If n is zero, return 0 as no numbers will be selected from 1 to maxSum. |
banned contains numbers outside the range [1, maxSum] | Ignore numbers in banned that are outside of the range [1, maxSum] since they cannot be chosen anyway. |
banned contains duplicate numbers | Treat duplicate numbers in banned as a single ban, a set or hashmap efficiently handles this. |
maxSum is very large, leading to potential integer overflow | Ensure that the running sum of selected numbers uses a data type large enough to prevent integer overflow, such as long. |
All numbers in the range [1, maxSum] are banned | If all numbers in the range are banned, return 0 as no numbers can be chosen. |
maxSum is smaller than 1 | If maxSum is less than 1 return 0, as the range [1, maxSum] will be empty or invalid. |