依次讀入乙個整數序列,每當已經讀入的整數個數為奇數時,輸出已讀入的整數構成的序列的中位數。詳細內容最樸素寫法,每到奇數時位將前面所有資料排序,找到中位數
每次sort是\(o(nlog_n)\),一組資料需要sort \(\frac\)次,所以複雜度為\(o(n^2log_n)\)
#include #include using namespace std;
const int m = 10010;
int a[m];
int main()
}if (cnt % 10) cout << endl; // 解決最後一行資料不夠10個,上方未輸出空行,會導致下面組的格式出問題
}return 0;
}
尋找中位數,上述做法採用\(o(nlog_n)\)的快速排序,也可以採用o(n)的快速選擇
所以每組的複雜度就變為了\(o(n^2)\)
#include #include using namespace std;
const int m = 10010;
int a[m];
int qsort(int a, int l, int r, int k)
int sl = j - l + 1;
if (k <= sl) return qsort(a, l, j, k);
return qsort(a, j + 1, r, k - sl);
}int main()
}if (cnt % 10) cout << endl; // 解決最後一行資料不夠10個,上方未輸出空行,會導致下面組的格式出問題
}return 0;
}
應用場景維護動態區間的中位數
小根堆始終維護大於大根堆堆頂元素的元素,大根堆維護小於大根堆堆頂元素的元素,由於我們保證大根堆元素個數最多比小根堆元素個數多1,所以在奇數個元素的情況下,兩個堆的元素數量不會相等,一定是相差1,大根堆堆頂元素恰好位於中位數的位置,每個資料插入堆中是\(o(log_n)\)的,所以每組的時間複雜度為\(o(nlog_n)\)
之所以能夠想到這樣的解法,是因為我們確定中位數其實並不需要保證其左右兩側資料的有序性,只要左側資料都小,右側資料都大即可,使用兩個堆恰好能夠維護這種性質
#include #include #include using namespace std;
int main()
}if (cnt % 10) cout << endl; // 解決最後一行資料不夠10個,上方未輸出空行,會導致下面組的格式出問題
}return 0;
}
動態維護數列的中位數
問題陳述 有個需要動態更新 插入或刪除 的數列l,現在需要隨時獲取到該數列的中位數,請設計相應的資料結構和演算法。演算法 令l的中位數為m,用乙個大頂堆儲存數列l中不大於m的元素 即l按從小到大排列時的前半部分 用乙個小頂堆儲存數列l中不小於m的元素 即l按從小到大排列時的後半部分 其中這兩個大小頂...
動態中位數
178.動態中位數 統計描述 提交自定義測試 題目描述 輸入n個32位有符號整數,當已輸入的個數為奇數個時,輸出此時的中位數。輸入描述 第一行乙個整數n 第二行n個32位有符號整數。輸出描述 輸出一行,n 2 上取整 個中位數,中間用空格隔開。對於 40 資料 n 1000 對於所有資料 n 100...
動態中位數
依次讀入乙個整數序列,每當已經讀入的整數個數為奇數時,輸出已讀入的整數構成的序列的中位數。輸入格式 第一行輸入乙個整數p,代表後面資料集的個數,接下來若干行輸入各個資料集。每個資料集的第一行首先輸入乙個代表資料集的編號的整數。然後輸入乙個整數m,代表資料集中包含資料的個數,m一定為奇數,資料之間用空...