이 기사에서는 문제가 주어지고 배열이 주어지며 응답해야 하는 두 가지 유형의 쿼리가 있습니다.
- 0 유형 − x(주어진 값)보다 크거나 같은 큰 요소의 수를 계산해야 합니다.
- 유형 1 − x(주어진 값)보다 엄격하게 큰 요소의 수를 계산해야 합니다.
여기 간단한 예가 있습니다 -
입력 :arr[] ={ 10, 15, 30, 40, 45 } and Q =3 Query 1:0 50 Query 2:1 40 Query 3:0 30Output :0 1 3Explanation:x =50, q =0 :50.x =40보다 크거나 같은 요소가 없습니다. 사전>해결책을 찾기 위한 접근 방식
솔루션을 찾기 위해 두 가지 다른 방법을 사용할 수 있습니다. 먼저 무차별 대입 솔루션을 사용한 다음 더 높은 제약 조건에서 작동할 수 있는지 확인합니다. 그렇지 않은 경우 솔루션 최적화를 진행합니다.
무차별 대입 접근
이 접근 방식에서는 모든 q 쿼리에 대한 배열을 탐색하고 주어진 조건을 충족하는 숫자를 찾습니다.
예시
#include네임스페이스 사용 std;void query(int *arr, int n, int type, int val) { int count =0; // 대답 if(!type) { // 유형 0 쿼리를 요청할 때(int i =0; i =val) count++; } } else { // 유형 1 쿼리를 요청할 때(int i =0; i val) count++; } } cout < 출력
013위의 접근 방식에서는 단순히 배열을 탐색하고 쿼리에 대한 답을 계산합니다. 이 접근 방식은 주어진 예에서 작동하지만 더 높은 제약 조건이 발생하면 프로그램의 전체 시간 복잡성이 O(N*Q)이므로 이 접근 방식은 실패합니다. 여기서 N은 배열의 크기이고 Q는 쿼리 수입니다. 이제 더 높은 제약 조건에서도 작동하도록 이 접근 방식을 최적화할 것입니다.
효율적인 접근
이 접근 방식에서는 이진 검색을 사용하여 주어진 값의 상한과 하한을 찾습니다. 먼저 이진 검색을 사용하여 배열을 정렬한 다음 그에 따라 하한 및 상한 함수를 적용합니다.
예시
#include네임스페이스 std;void lowerbound(int *arr, int n, int val) { int l =-1, r =n; while(r - l> 1) { // 답을 이진법으로 검색 int mid =(l+r)/2; if(arr[mid]>=val) r =중간; 그렇지 않으면 l =중간; } if(r ==n) // r이 움직이지 않으면 조건 cout <<"0\n"; else cout < 1) { // 답을 이진법으로 검색 int mid =(l+r)/2; if(arr[mid]> val) r =중간; 그렇지 않으면 l =중간; } if(r ==n)// r이 움직이지 않으면 cout <<"0\n" 조건을 충족하는 요소가 없음을 의미합니다. else cout < 출력
012위의 코드는 시간 복잡도를 상당히 줄이는 이진 검색에서 작동합니다. 따라서 최종 복잡성은 O(NlogN)가 됩니다. , 여기서 N은 배열의 크기입니다.
위 코드 설명
이 접근 방식에서는 이진 검색을 사용하여 주어진 값의 상한과 하한을 찾습니다. 이제 이진 검색의 경우 정렬된 배열에서만 작동하므로 먼저 배열을 정렬합니다. 배열을 정렬했으므로 유형 0, 유형 1 조건을 각각 충족하는 첫 번째 숫자를 찾는 데 도움이 되는 하한 및 상한 함수를 만듭니다. 조건에 도움이 되는 첫 번째 숫자를 찾았으므로 이 요소 뒤에 오는 요소도 조건을 따르므로 이 요소의 인덱스와 N(배열의 크기)의 차이를 인쇄합니다.
결론
이 기사에서는 이진 검색을 사용하여 보다 크거나 작지 않은 쿼리를 해결하는 문제를 해결합니다. 우리는 또한 이 문제에 대한 C++ 프로그램과 이 문제를 해결하는 완전한 접근 방식( Normal 및 Efficient)을 배웠습니다. C, Java, python 및 기타 언어와 같은 다른 언어로 동일한 프로그램을 작성할 수 있습니다. 이 기사가 도움이 되기를 바랍니다.