TIL
[코테 연습] 962. Maximum Width Ramp
크라00
2024. 10. 10. 14:15
- 스택 / 단조스택 ( monototic stack ) / 배열문제
- 문제분석
1. 양수의 숫자가 나열되어있는 nums 배열이 있다.
2. i < j 를 만족하며, j - i 가 가장 크고, nums[i] 와 nums[j] 가 같거나 nums[j] 가 큰 숫자 중 너비 값이 가장 큰 ramp 를 구하라.
- 문제풀이
1. Stack 을 선언하여 단조 감소 스택을 만든다.
1-1. 단조 감소 스택을 구성한다는 의미는 Stack 에 저장된 값들이 항상 내림차순을 유지하도록 값을 삽입하는 것이다.
1-2. 즉, 스택에 들어가는 값들이 스택의 상단에서 하단으로 갈수록 작아지는 구조를 유지하는 것.
2. 단조 감소 스택을 만들기 위해서는 nums 의 배열을 반복문으로 처리하며, stack에 담겨 있는 값이 nums[i] 값 보다 커야한다.
- nums[stack.peek()] > nums[i]가 성립할 때만 i를 스택에 삽입합니다.
- 이렇게 하면, 스택 안에 있는 인덱스들은 모두 그에 해당하는 nums 배열 값들이 단조 감소하는 순서로 정렬됩니다. 즉, 스택에서 꺼낼 때는 항상 더 작은 값들이 먼저 나오게 됩니다.
- 예시:
- int[] nums = {6, 0, 8, 2, 1, 5};
- 처음 배열을 순회하며 nums의 인덱스들을 스택에 넣을 때, 스택이 항상 단조 감소 순서를 유지하도록 삽입합니다:
- i = 0, nums[0] = 6 -> 스택: [0]
- i = 1, nums[1] = 0 -> nums[1] < nums[0] 이므로 삽입 -> 스택: [1, 0]
- i = 2, nums[2] = 8 -> nums[2] > nums[1] 이므로 삽입하지 않음
- i = 3, nums[3] = 2 -> nums[3] > nums[1] 이므로 삽입하지 않음
- i = 4, nums[4] = 1 -> nums[4] < nums[3] 이므로 삽입 -> 스택: [4, 1, 0]
- i = 5, nums[5] = 5 -> nums[5] > nums[4] 이므로 삽입하지 않음
3. nums 를 내림차순으로 반복하면서, nums[stack.peek()] <= nums[i] 의 조건을 만족하는 것을 확인하며 가장 큰 j - i 를 찾는다.
> java
class Solution {
public int maxWidthRamp(int[] nums) {
Deque<Integer> deque = new ArrayDeque<>();
for (int i = 0; i < nums.length; i++) {
//deque 가 비어있거나, deque 의 숫자가 nums[i] 의 숫자보다 큰 경우 deque 에 넣는다.
// 이렇게 하면 deque 에는 nums[i] 보다 큰 숫자의 index 만 남아있게 된다.
if (deque.isEmpty() || nums[deque.peek()] > nums[i]) {
deque.push(i);
}
}
int max = 0;
for (int i = nums.length-1; i >= 0; i--) {
// deque 를 pop() 했을 때, deque 에 있는 index의 값보다 작거나 큰 값을 max 로 정의하게된다.
while (!deque.isEmpty() && nums[deque.peek()] <= nums[i]) {
max = (int)Math.max(max, i - deque.pop());
}
}
return max;
}
}
> python
class Solution:
def maxWidthRamp(self, nums: List[int]) -> int:
n = len(nums)
arr = []
for i in range(n) :
if not arr or nums[arr[-1]] > nums[i] :
arr.append(i)
_max = 0
for i in range(n) :
j = n - 1 - i
while arr and nums[arr[-1]] <= nums[j] :
_max = max(_max, j - arr.pop())
return _max