이코테_고정점 찾기 (이진탐색_인덱스 범위로 이진탐색하기)

RostoryT·2022년 9월 5일
0

Binary Search

목록 보기
7/8

고정점 찾기

메모

arr[i] == i 인 것을 찾아야함 (없는경우 -1)

arr[i] < 0 인경우는 일단 걸러

arr은 오름차순 정렬로 주어지고, O(logN) 알고리즘으로 설계하지 않으면 시간초과

어떻게풀어..?

동빈나의 해설

  • 찾고자 하는 값이 '중간점'과 동일하다고 가정하고 이진탐색을 적용해야함
  • 중간점이 가리키는 위치의 값보다 중간점이 작은 경우 -> 왼쪽 부분을 탐색
  • 큰 경우 -> 오른쪽을 탐색

알고리즘 및 방법

앞에서부터 브루트포스하면 되지만, O(n)은 시간초과라고 하니

이진탐색으로 pivot부터 보는데

정렬되어있기 때문에,
pivot이 arr[pivot] 보다 작으면 => 범위 왼쪽으로 좁혀
pivot이 arr[pivot] 보다 크면 => 범위 오른쪽으로 좁혀

  • pivot은 인덱스값이고, 매번 갱신됨
  • 설명
    -15 -4 2 8 9 13 15 가 있을 때

pivot = 4
arr[pivot] = 8


솔루션 코드 - 내가 푼

  • python
n = int(input())
arr = list(map(int, input().split()))
flag = False
start = 0
end = n-1

while start <= end:
    pivot = (end+start)//2
    print( start, end, pivot)
    if pivot == arr[pivot]:
        ans = arr[pivot]
        flag = True
        break
    if pivot < arr[pivot]:
        end = pivot-1
    elif pivot > arr[pivot]:
        start = pivot+1
        
print(ans if flag else -1)



  • cpp (동빈나)
    • 재귀로 했을 뿐, 똑같음(파이썬코드랑 다른 주의할만한 문법은 없음)
#include <bits/stdc++.h>

using namespace std;

// 이진 탐색 소스코드 구현(재귀 함수)
int binarySearch(vector<int>& arr, int start, int end) {
    if (start > end) return -1;
    int mid = (start + end) / 2;
    // 고정점을 찾은 경우 중간점 인덱스 반환
    if (arr[mid] == mid) return mid;
    // 중간점의 값보다 중간점이 작은 경우 왼쪽 확인
    else if (arr[mid] > mid) return binarySearch(arr, start, mid - 1);
    // 중간점의 값보다 중간점이 큰 경우 오른쪽 확인
    else return binarySearch(arr, mid + 1, end);
}

int n;
vector<int> arr;

int main(void) {
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        arr.push_back(x);
    }

    // 이진 탐색(Binary Search) 수행
    int index = binarySearch(arr, 0, n - 1);

    // 결과 출력
    cout << index << '\n';
}
profile
Do My Best

0개의 댓글