암호:
class Solution {
public int peakIndexInMountainArray(int[] arr) {
int left=0,right=arr.length-1;
while (left<right){
int mid=left+(right-left+1)/2;
if(arr[mid]>arr[mid-1]){
left=mid;
}else {
right=mid-1;
}
}
return left;
}
}
답변:
질문의 요구사항을 간단히 분석해 보면, 우선 질문에 제시된 정보는 다음과 같습니다.
1. 산 배열의 길이 > = 3, 이는 각 배열에 정점이 있어야 함을 의미합니다.
2. 산 배열은 정수로 구성됩니다.
3. 다음을 만족하는 첨자를 찾아야 합니다. arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
i
따라서 배열의 구조는 다음과 같습니다.
예를 들어 배열 arr =[1,2,3,2,1]일 때 우리가 찾고 있는 정점은 3이고 아래 첨자는 2입니다.
위의 배열을 분석하면 배열을 두 개의 간격으로 나눌 수 있습니다. [1, 2, 3]은 증가 간격, [2, 1]은 감소 간격, 그림의 구분은 다음과 같습니다.
이 나눗셈을 통해 우리가 찾고 있는 데이터는 증가 구간의 오른쪽 경계가 되며, 배열에서 무작위로 숫자 arr[i]를 선택할 때 arr[i] > arr[i-1이면 ], 이는 숫자가 증가하는 범위에 있음을 의미하므로 숫자 왼쪽에 있는 데이터를 대담하게 제외할 수 있습니다( 그러나 숫자를 제외할 수는 없습니다, 왜냐하면 우리가 얻고자 하는 답은 증가하는 구간에서 그 숫자가 우리가 원하는 답과 정확히 일치하는지 확신할 수 없기 때문입니다.)
arr[ i ] < arr[ i-1 ] 이면 숫자가 감소하는 범위에 있다는 뜻이고 과감하게 숫자와 숫자 오른쪽에 있는 데이터를 제외할 수 있습니다.
위의 분석을 통해 우리는 이 질문이 2단계 성격을 가지고 있다는 것을 알았으므로 이분법적 방법을 사용하여 이 문제를 해결할 수 있습니다.
arr =[1,2,3,2,1]의 예도 마찬가지입니다.
L 및 R 포인터를 왼쪽 및 오른쪽 경계로 가리키고 mid = L + (R- L+1)/2 = 3을 계산합니다. arr[ mid ] > arr[ mid -1 ]이므로 mid가 가리키는 값은 증가하는 범위에 있습니다. L=mid로 설정합니다.
1 2 3 2 1
L 중간 R
mid = 3을 계산하면 이때 arr[ mid ] < arr[ mid -1 ]이므로 mid가 가리키는 값이 감소하는 범위에 있으므로 R = mid -1이라고 하자.
1 2 3 2 1
L 중간 R
L 포인터와 R 포인터가 만났다는 것은 조건에 맞는 값을 찾았다는 뜻이고, L 포인터가 가리키는 위치를 반환할 수 있다는 뜻이다.
1 2 3 2 1
엘
아르 자형