K 작은 수치 쌍 (정렬 구 해 O (N * logN), BFPRT 구 해 O (N)))
37274 단어 알고리즘 과 데이터 구조알고리즘
복잡 도 O (N * logN) 의 해법
/* : ,
,
*/
#include
#include
#include
using namespace std;
// O(N*logN)
vector<int> getPairKth(vector<int>& arr, int k) {
if (arr.empty() || arr.size() * arr.size() <= k || k < 0) {
return vector<int>();
}
// O(N*logN)
sort(arr.begin(), arr.end());
// pair
int firstDim = k / arr.size();
//
int lessFirst = 0;
int equalFirst = 0;
for (int i = 0; i < arr.size() && arr.at(i) <= arr.at(firstDim); i++) {
arr.at(i) == arr.at(firstDim) ? equalFirst++ : lessFirst++;
}
int secondDim = (k - lessFirst * arr.size()) / equalFirst;
vector<int> res{
arr.at(firstDim), arr.at(secondDim) };
return res;
}
int main() {
vector<int> arr{
3, 1, 2 };
vector<int> pairKth = getPairKth(arr, 5);
if (!pairKth.empty()) {
cout << "(" << pairKth.at(0) << ", " << pairKth.at(1) << ")" << endl;
}
else {
cout << "pairKth.empty() == true" << endl;
}
system("pause");
return 0;
}
시간 복잡 도가 O (N) 인 해법
/* : ,
( BFPRT O(N) )
( :O(N))
( BFPRT O(N) )
*/
#include
#include
#include
using namespace std;
// BFPRT K ( ) O(N),
class BFPRT {
public:
int getMinKthByBFPRT(vector<int>& arr, int k, int left, int right) {
if (arr.empty() || k >= arr.size() || left > right || k < left || k > right) {
return -1;
}
if (left == right) {
return arr.at(k);
}
int pivot = medianOfMedians(arr, left, right);
vector<int> range = partition(arr, left, right, pivot);
if (k > range.at(0) && k < range.at(1)) {
return arr.at(k);
}
return k <= range.at(0) ? getMinKthByBFPRT(arr, k, left, range.at(0)) :
getMinKthByBFPRT(arr, k, range.at(1), right);
}
int medianOfMedians(vector<int>& arr, int left, int right) {
vector<int> medians;
int offset = (right - left + 1) % 5 == 0 ? 0 : 1;
int groupNums = (right - left + 1) / 5 + offset;
for (int i = 0; i < groupNums; i++) {
int tmpL = left + i * 5;
int tmpR = tmpL + 5;
sort(arr.begin() + tmpL, arr.begin() + min(tmpR, right));
medians.push_back(arr.at(tmpL + ((min(tmpR, right) - tmpL) >> 1)));
}
return getMinKthByBFPRT(medians, medians.size() / 2, 0, medians.size() - 1);
}
vector<int> partition(vector<int>& arr, int left, int right, int pivot) {
int tmpL = left - 1;
int tmpR = right + 1;
int index = left;
while (index < tmpR) {
if (arr.at(index) < pivot) {
swap(arr, index++, ++tmpL);
}
else if (arr.at(index) > pivot) {
swap(arr, index, --tmpR);
}
else {
index++;
}
}
vector<int> res{
tmpL, tmpR };
return res;
}
void swap(vector<int>& arr, int n1, int n2) {
int tmp = arr.at(n1);
arr.at(n1) = arr.at(n2);
arr.at(n2) = tmp;
}
};
// O(N)
vector<int> getPairKth(vector<int>& arr, int k) {
if (arr.empty() || k < 0 || k >= arr.size() * arr.size()) {
return vector<int>();
}
int firstDim = k / arr.size();
// BFPRT K O(N)
int firstNum = BFPRT().getMinKthByBFPRT(arr, firstDim, 0, arr.size() - 1);
// O(N)
int lessFirstNums = 0;
int equalFirstNums = 0;
for (int i = 0; i < arr.size() && arr.at(i) <= firstNum; i++) {
arr.at(i) == firstNum ? equalFirstNums++ : lessFirstNums++;
}
int secondDim = (k - lessFirstNums * arr.size()) / equalFirstNums;
// BFPRT K O(N)
int secondNum = BFPRT().getMinKthByBFPRT(arr, secondDim, 0, arr.size() - 1);
vector<int> pairKth{
firstNum, secondNum };
return pairKth;
}
int main() {
vector<int> arr{
3, 1, 2 };
vector<int> pairKth = getPairKth(arr, 5);
if (!pairKth.empty()) {
cout << "(" << pairKth.at(0) << ", " << pairKth.at(1) << ")" << endl;
}
else {
cout << "pairKth.empty() == true" << endl;
}
system("pause");
return 0;
}
권리 침해 가 있 으 면 삭제 에 연락 하 십시오. 오류 가 있 으 면 지적 해 주 십시오. 감사합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
데이터 구조의 링크 의 실현글 목록 소개 실현 1. 프로필 동적 배열, 스 택 과 대열 의 바 텀 은 모두 정적 배열 에 의존 하고 resize 로 고정 용량 문 제 를 해결한다.그리고 링크 는 진정한 동적 데이터 구조 이다 2. 실현...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.