Sweet And Savory
Sweet And Savory
Category
Arrays
Difficulty
Medium
Problem Statement
You are given an array of dish flavors where negative values represent sweet dishes and positive values represent savory dishes. You need to find one sweet and one savory dish whose combined flavor is as close to a given target as possible without exceeding it. If no valid pair exists, return [0, 0]. The target is always non-negative.
Intuition
After sorting the dishes, we can use a two-pointer technique with one pointer on the most negative (sweetest) dish and one on the most positive (most savory) dish. By moving the pointers inward based on whether the current sum is below or above the target, we efficiently explore candidate pairs.
Approach
- Sort the array.
- Place
leftat index 0 (most sweet) andrightat the last index (most savory). - Initialize
bestPair = [0, 0]andbestDiff = infinity. - While
left < rightandarray[left] < 0andarray[right] > 0:- Compute
sum = array[left] + array[right]. - If
sum <= target:- Compute
diff = target - sum. - If
diff < bestDiff, updatebestDiff = diffandbestPair = [array[left], array[right]]. - Move
leftrightward (increase the sum toward target).
- Compute
- Else (
sum > target):- Move
rightleftward (decrease the sum toward target).
- Move
- Compute
- Return
bestPair.
Pseudocode
function sweetAndSavory(dishes, target):
sort(dishes)
left = 0
right = length(dishes) - 1
bestPair = [0, 0]
bestDiff = infinity
while left < right and dishes[left] < 0 and dishes[right] > 0:
sum = dishes[left] + dishes[right]
if sum <= target:
diff = target - sum
if diff < bestDiff:
bestDiff = diff
bestPair = [dishes[left], dishes[right]]
left += 1
else:
right -= 1
return bestPair
Time & Space Complexity
- Time: O(n log n) — dominated by sorting. The two-pointer scan is O(n).
- Space: O(1) — aside from the sort, only a constant number of variables are used.
Key Insights
- The constraint that we need one sweet (negative) and one savory (positive) dish simplifies pointer management:
leftstays in the negative region andrightin the positive region. - We only consider sums at or below the target (never exceeding), so we move left forward when the sum is too small and right backward when too large.
- If
sum == target, that is the best possible result and we can return immediately (though the algorithm handles this naturally).
Edge Cases
- No sweet dishes or no savory dishes: no valid pair exists, return
[0, 0]. - Target is 0: we want the pair whose sum is the largest non-positive value (closest to zero from below).
- All pairs exceed the target: return
[0, 0]. - Multiple pairs with the same best difference: the first one found during the sweep is returned.