[검 지 Offer] 데이터 흐름 의 중위 수
20475 단어 데이터
어떻게 데이터 흐름 중의 중위 수 를 얻 습 니까?데이터 흐름 에서 홀수 수 수 치 를 읽 으 면 중위 수 는 모든 수치 가 정렬 된 후에 중간 에 있 는 수치 입 니 다.데이터 흐름 에서 짝수 수 수 치 를 읽 으 면 중위 수 는 모든 수치 가 정렬 된 후 중간 두 수의 평균 값 이다.
데이터 흐름 에 대응 하 는 것 은 바로 온라인 알고리즘 입 니 다. 전형 적 인 문 제 는 1 억 개의 숫자 에서 가장 큰 100 개의 수 를 찾 는 것 입 니 다. 이것 은 응용 문제 입 니 다. 가장 큰 100 개의 수 를 찾 으 면 우 리 는 크기 가 100 인 최소 화 더 미 를 만 듭 니 다. 모든 원 소 는 쌓 인 요소 와 비교 합 니 다. 쌓 인 요 소 는 현재 100 대 에서 가장 작은 숫자 이기 때 문 입 니 다.온 원소 가 이 원소 보다 크 면 원래 의 쌓 인 지붕 을 교체 합 니 다.
그러면 이 문제 에 대해 서 는 요?단순히 모든 요 소 를 한 배열 에 넣 으 면 중위 수 를 찾 을 때마다 가장 빠 르 고 O (n) 가 필요 하 며 종합 하면 O (n ^ 2) 의 복잡 도 입 니 다.우 리 는 위의 예 에서 의 아 이 디 어 를 이용 하여 현재 n / 2 작은 요 소 를 최대 더미 로 유지 할 수 있 습 니 다. 그러면 매번 중위 수 를 찾 을 때마다 더미 꼭대기 만 꺼 내 면 됩 니 다.그러나 한 가지 문제 가 있 습 니 다. 데 이 터 는 동태 적 으로 증가 해 야 합 니 다. 예전 에 교 체 된 요소 가 요소 의 증가 에 따라 다시 달 려 올 수 있 습 니 다. 그래서 우 리 는 단순히 위 문제 처럼 요 소 를 버 릴 수 없습니다. 우 리 는 최소 화 된 더미 로 n / 2 큰 요 소 를 저장 할 수 있 습 니 다.
1 #include <bits/stdc++.h>
2 using namespace std;
3
4 class Solution {
5 private:
6 vector<int> min; //
7 vector<int> max; //
8 public:
9 void Insert(int num) {
10 if(((min.size()+max.size()) & 1) == 0) { // ,
11 if(max.size() > 0 && num < max[0]) {
12 max.push_back(num);
13 push_heap(max.begin(), max.end(), less<int>());
14 num=max[0];
15 pop_heap(max.begin(), max.end(), less<int>());
16 max.pop_back();
17 }
18 min.push_back(num); //
19 push_heap(min.begin(), min.end(), greater<int>());
20 } else {
21 if(min.size() > 0 && num > min[0]) { // ,
22 min.push_back(num);
23 push_heap(min.begin(), min.end(), greater<int>());
24 num=min[0];
25 pop_heap(min.begin(), min.end(), greater<int>());
26 min.pop_back();
27 }
28 max.push_back(num); //
29 push_heap(max.begin(), max.end(), less<int>());
30 }
31 }
32
33 double GetMedian() {
34 int size=min.size() + max.size();
35 if(size==0) return -1;
36 double median = 0;
37 if((size&1) != 0) {
38 median = (double) min[0];
39 } else {
40 median = (double) (max[0] + min[0]) / 2;
41 }
42 return median;
43 }
44 };
45
46 int main() {
47 Solution s;
48 vector<int> v{5,2,3,4,1,6,7,0,8};
49 for (int i = 0; i < v.size(); ++i) {
50 s.Insert(v[i]);
51 cout << s.GetMedian() << endl;
52 }
53 return 0;
54 }
멀 티 셋 을 사용 하여 프로 그래 밍 을 간소화 할 수도 있 고, lintcode 에 도 원제 가 있다.
http://www.lintcode.com/en/problem/data-stream-median/
1 class Solution {
2 public:
3 /**
4 * @param nums: A list of integers.
5 * @return: The median of numbers
6 */
7 vector<int> medianII(vector<int> &nums) {
8 // write your code here
9 multiset<int> left, right;
10 vector<int> res;
11 bool flag = true;
12 for (int n : nums) {
13 int tmp = n;
14 if (flag) {
15 if (!right.empty() && n > *right.begin()) {
16 right.insert(n);
17 tmp = *right.begin();
18 right.erase(right.find(tmp));
19 }
20 left.insert(tmp);
21 } else {
22 if (!left.empty() && n < *left.rbegin()) {
23 left.insert(n);
24 tmp = *left.rbegin();
25 left.erase(left.find(tmp));
26 }
27 right.insert(tmp);
28 }
29 flag = !flag;
30 res.push_back(*left.rbegin());
31 }
32 return res;
33 }
34 };
또 하 나 는 미끄럼 창의 중위 수 를 구 하 는 것 이지 사실은 같은 사상 에 기초 한 것 이다.다만 창 이 미 끄 러 질 때 요소 가 창 에서 미 끄 러 지기 때문에 새로운 요 소 를 삽입 하기 전에 미 끄 러 지 는 요 소 를 삭제 해 야 합 니 다.
http://www.lintcode.com/en/problem/sliding-window-median/
1 class Solution {
2 public:
3 /**
4 * @param nums: A list of integers.
5 * @return: The median of the element inside the window at each moving
6 */
7 vector<int> medianSlidingWindow(vector<int> &nums, int k) {
8 // write your code here
9 vector<int> res;
10 if (k > nums.size() || k == 0) return res;
11 multiset<int> left, right;
12 //init heaps by first kth elements in nums
13 for (int i = 0; i < k; ++i) {
14 left.insert(nums[i]);
15 }
16 while (left.size() > (k + 1) / 2) {
17 right.insert(*left.rbegin());
18 left.erase(left.find(*left.rbegin()));
19 }
20 res.push_back(*left.rbegin());
21 //slide window
22 for (int i = k; i < nums.size(); ++i) {
23 //delete the leftmost element in window from heaps
24 if (nums[i-k] > res.back()) right.erase(right.find(nums[i-k]));
25 else left.erase(left.find(nums[i-k]));
26 //insert new element into heaps
27 if (!left.empty() && nums[i] <= *left.rbegin()) left.insert(nums[i]);
28 else right.insert(nums[i]);
29 //adjust heaps so that the left heap contains (k + 1) / 2 elements
30 while (left.size() < (k + 1) / 2) {
31 left.insert(*right.begin());
32 right.erase(right.begin());
33 }
34 while (left.size() > (k + 1) / 2) {
35 right.insert(*left.rbegin());
36 left.erase(left.find(*left.rbegin()));
37 }
38 res.push_back(*left.rbegin());
39 }
40 return res;
41 }
42 };
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Spark에서 OpenStack Swift 기반 IBM Object Storage에 연결해 본 메모Spark와 같은 빅데이터 전제라면 로그 파일 등이 상정되는 경우도 많을 것입니다만, 일반적인 비즈니스 데이터는 피해서 통과할 수 없기 때문에 우선은 CSV, 라고 하는 것으로 CSV 주위를 조금 시험해 보았을 때 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.