Sum of Beauty in the Array
MedPrompt
You are given a 0-indexed integer array nums. For each index i (1 <= i <= nums.length - 2) the beauty of nums[i] equals:
2, ifnums[j] < nums[i] < nums[k], for all0 <= j < iand for alli < k <= nums.length - 1.1, ifnums[i - 1] < nums[i] < nums[i + 1], and the previous condition is not satisfied.0, if none of the previous conditions holds.
Return the sum of beauty of all nums[i] where 1 <= i <= nums.length - 2.
Example 1:
Input: nums = [1,2,3]
Output: 2
Explanation: For each index i in the range 1 <= i <= 1:
- The beauty of nums[1] equals 2.Example 2:
Input: nums = [2,4,6,4]
Output: 1
Explanation: For each index i in the range 1 <= i <= 2:
- The beauty of nums[1] equals 1.
- The beauty of nums[2] equals 0.Example 3:
Input: nums = [3,2,1]
Output: 0
Explanation: For each index i in the range 1 <= i <= 1:
- The beauty of nums[1] equals 0.
Constraints:
3 <= nums.length <= 1051 <= nums[i] <= 105
Approaches
2 approaches with complexity analysis and trade-offs.
This approach directly translates the problem statement into code. We iterate through each possible index i (from 1 to n-2) and, for each i, we check the conditions for beauty scores of 2, 1, and 0 in that specific order by scanning the left and right subarrays.
Algorithm
- Initialize a variable
totalBeautyto 0. - Loop through the array with an index
ifrom1tonums.length - 2. - Inside the loop, for each
nums[i]:- Check for beauty 2:
- Find the maximum element in the subarray
nums[0...i-1]by iterating fromj = 0toi-1. - Find the minimum element in the subarray
nums[i+1...n-1]by iterating fromk = i+1ton-1. - If
nums[i]is strictly greater than the found maximum and strictly less than the found minimum, add 2 tototalBeautyand continue to the nexti.
- Find the maximum element in the subarray
- Check for beauty 1:
- If the condition for beauty 2 is not met, check if
nums[i-1] < nums[i] < nums[i+1]. - If this local condition is true, add 1 to
totalBeauty.
- If the condition for beauty 2 is not met, check if
- Check for beauty 2:
- After the loop finishes, return
totalBeauty.
Walkthrough
The brute-force method involves a straightforward iteration through the relevant indices of the array. For each index i from 1 to n-2, we perform the checks as described in the problem.
-
Check for beauty of 2: We need to verify that
nums[i]is greater than every element before it and smaller than every element after it. This is done by two separate inner loops. The first inner loop finds the maximum element innums[0...i-1], and the second finds the minimum innums[i+1...n-1]. Ifnums[i]satisfies the condition, we add 2 to our total sum. -
Check for beauty of 1: If the first condition is not met, we proceed to check the simpler, local condition:
nums[i-1] < nums[i] < nums[i+1]. If this holds, we add 1 to the sum. -
Beauty of 0: If neither of the above conditions is true, the beauty is 0, and we add nothing.
This process is repeated for all applicable indices.
class Solution { public int sumOfBeauties(int[] nums) { int n = nums.length; int totalBeauty = 0; for (int i = 1; i < n - 1; i++) { // Find max on the left int maxLeft = 0; for (int j = 0; j < i; j++) { maxLeft = Math.max(maxLeft, nums[j]); } // Find min on the right int minRight = 100001; // Constraint: nums[i] <= 10^5 for (int k = i + 1; k < n; k++) { minRight = Math.min(minRight, nums[k]); } if (maxLeft < nums[i] && nums[i] < minRight) { totalBeauty += 2; } else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) { totalBeauty += 1; } } return totalBeauty; }}Complexity
Time
O(n^2) - The outer loop runs `n-2` times. Inside this loop, we iterate up to `i` times to find the left maximum and `n-1-i` times to find the right minimum. In total, the inner operations take O(n) time. Therefore, the total time complexity is O(n) * O(n) = O(n^2).
Space
O(1) - We only use a few variables to store the running sum, loop indices, and temporary max/min values. The space used does not depend on the size of the input array.
Trade-offs
Pros
Simple to understand and implement directly from the problem definition.
Uses constant extra space, making it memory efficient.
Cons
Highly inefficient due to nested loops and redundant calculations.
Will likely result in a 'Time Limit Exceeded' (TLE) error for large inputs as specified in the constraints.
The brute-force approach is slow because it repeatedly scans the left and right subarrays. We can optimize this by precomputing the necessary information. Specifically, for each index i, we need the maximum of all elements to its left and the minimum of all elements to its right. This can be done efficiently in linear time using auxiliary space.
Algorithm
- Get the length of the array,
n. - Create a
suffixMinarray of sizento store the minimum value from indexito the end of the array. - Populate
suffixMinby iterating fromn-2down to0. SetsuffixMin[i] = min(nums[i], suffixMin[i+1]). - Initialize
totalBeauty = 0. - Initialize a variable
prefixMax = nums[0]to keep track of the maximum value seen so far from the left. - Iterate
ifrom1ton-2:- Check for beauty of 2: If
prefixMax < nums[i] && nums[i] < suffixMin[i+1], add 2 tototalBeauty. - Else, check for beauty of 1: If
nums[i-1] < nums[i] && nums[i] < nums[i+1], add 1 tototalBeauty. - Update
prefixMax = max(prefixMax, nums[i])for the next iteration.
- Check for beauty of 2: If
- Return
totalBeauty.
Walkthrough
The core idea is to avoid re-computation by storing the results of prefix maximums and suffix minimums. A fully optimized approach would use two arrays, one for prefix maxes and one for suffix mins. However, we can optimize the space slightly by calculating the prefix maximums on-the-fly while iterating.
-
Precompute Suffix Minimums: We create an array, let's call it
suffixMin, wheresuffixMin[i]holds the minimum value in the subarraynums[i...n-1]. This can be calculated in a single pass from right to left.suffixMin[n-1] = nums[n-1]- For
ifromn-2down to0,suffixMin[i] = min(nums[i], suffixMin[i+1]).
-
Calculate Total Beauty in One Pass: After precomputing
suffixMin, we can iterate throughnumsfromi = 1ton-2. In this pass, we maintain a variableprefixMaxwhich stores the maximum value encountered so far (i.e.,max(nums[0...i-1])).- For each
nums[i], the condition for beauty 2,max(nums[0...i-1]) < nums[i] < min(nums[i+1...n-1]), can now be checked in O(1) time asprefixMax < nums[i] < suffixMin[i+1]. - If this is true, we add 2 to the total. Otherwise, we check the condition for beauty 1.
- After checking the conditions for
nums[i], we updateprefixMax = max(prefixMax, nums[i])before moving to the next index.
- For each
This combination of precomputation and a single main pass reduces the overall time complexity to linear.
class Solution { public int sumOfBeauties(int[] nums) { int n = nums.length; // suffixMin[i] stores the minimum value in nums[i...n-1] int[] suffixMin = new int[n]; suffixMin[n - 1] = nums[n - 1]; for (int i = n - 2; i >= 0; i--) { suffixMin[i] = Math.min(nums[i], suffixMin[i + 1]); } int totalBeauty = 0; int prefixMax = nums[0]; // Stores the maximum value in nums[0...i-1] for (int i = 1; i < n - 1; i++) { // Check for beauty of 2 if (prefixMax < nums[i] && nums[i] < suffixMin[i + 1]) { totalBeauty += 2; } // Check for beauty of 1 else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) { totalBeauty += 1; } // Update prefixMax for the next iteration prefixMax = Math.max(prefixMax, nums[i]); } return totalBeauty; }}Complexity
Time
O(n) - The algorithm consists of two main passes over the array. The first pass to populate the `suffixMin` array takes O(n) time. The second pass to calculate the total beauty also takes O(n) time. Therefore, the total time complexity is O(n) + O(n) = O(n).
Space
O(n) - We use an auxiliary array `suffixMin` of size `n` to store the suffix minimums. The space for `prefixMax` and other variables is constant, so the overall space complexity is dominated by the `suffixMin` array.
Trade-offs
Pros
Highly efficient with linear time complexity, making it suitable for large inputs.
The logic is a clear optimization of the brute-force method, avoiding redundant work.
Cons
Requires extra space proportional to the input size, which might be a concern for extremely large inputs in a memory-constrained environment (though acceptable for this problem's constraints).
Solutions
Solution
class Solution {public int sumOfBeauties(int[] nums) { int n = nums.length; int[] right = new int[n]; right[n - 1] = nums[n - 1]; for (int i = n - 2; i > 0; --i) { right[i] = Math.min(right[i + 1], nums[i]); } int ans = 0; int l = nums[0]; for (int i = 1; i < n - 1; ++i) { int r = right[i + 1]; if (l < nums[i] && nums[i] < r) { ans += 2; } else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) { ans += 1; } l = Math.max(l, nums[i]); } return ans; }}class Solution {public: int sumOfBeauties(vector<int> &nums) { int n = nums.size(); vector<int> right(n, nums[n - 1]); for (int i = n - 2; i; --i) { right[i] = min(right[i + 1], nums[i]); } int ans = 0; for (int i = 1, l = nums[0]; i < n - 1; ++i) { int r = right[i + 1]; if (l < nums[i] && nums[i] < r) { ans += 2; } else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) { ans += 1; } l = max(l, nums[i]); } return ans; }};class Solution: def sumOfBeauties(self, nums: List[int]) -> int: n = len(nums) right = [nums[- 1]] * n for i in range(n - 2, - 1, - 1): right[i] = min(right[i + 1], nums[i]) ans = 0 l = nums[0] for i in range(1, n - 1): r = right[i + 1] if l < nums[i] < r: ans += 2 elif nums[i - 1] < nums[i] < nums[i + 1]: ans += 1 l = max(l, nums[i]) return ansVideo walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.