[코딩테스트 스터디/C++] Zoho인터뷰 정렬된배열에서특정수의개수구하기

1 분 소요

1.문제

N개의 원소를 포함하고 있는 수열이 오름차순으로 정렬되어 있다. 이때 이 수열에서 x가 등장하는 횟수를 계산하시오. 단, 이 문제는 시간 복잡도 O(logN)으로 알고리즘을 설계하시오. 수열의 원소 중에서 값이 x인 원소가 없다면 -1을 출력한다.



2. 풀이 전 계획과 생각

  • 이진 탐색 사용



3. 풀이

#include<iostream>
#include<vector>
#include<algorithm> 
using namespace std;

// 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수
int countByRange(vector<int>& v, int leftValue, int rightValue) {
    vector<int>::iterator rightIndex = upper_bound(v.begin(), v.end(), rightValue);
    vector<int>::iterator leftIndex = lower_bound(v.begin(), v.end(), leftValue);
    return rightIndex - leftIndex;
}

int n, x;

vector<int> v;

int main() {
    // 입력
    cin >> n >> x;

    // 입력
    for (int i = 0; i < n; i++) {
        int temp; cin >> temp;
        v.push_back(temp);
    }

    // 이진탐색  
    int ans = countByRange(v, x, x);

    // 답 출력  
    if (ans == 0) cout << -1;  
    else cout << ans;  
}

upper_bound, lower_bound 모두 이진탐색 기반의 탐색 방법이라 정렬된 배열이나 벡터에 사용이 가능하다. 반환형은 Iterator 이다. 이진탐색이라 시간복잡도 조건을 만족할 수 있다.

upper_bound는 찾으려는 key 값을 초과하는 숫자가 배열 몇 번째에서 처음 등장하는지 찾을 수 있다.

lower_bound는 찾으려는 key 값보다 같거나 큰 숫자가 배열 몇 번째에서 처음 등장하는지 찾을 수 있다.



4. 풀이하면서 고민했던 점

  • 처음에 이진탐색으로 x원소를 찾고 그 앞, 뒤 원소를 순회하면서 찾으려고 했는데 생각해보니 최악의 경우 시간복잡도가 O(N)이라서 실패함



5. 문제를 풀고 알게된 개념 및 소감

  • upper_bound, lower_bound에 대해 알게되었다.