日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

寻找多数元素

發布時間:2025/5/22 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 寻找多数元素 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/*** -*- coding : utf-8 -*-* @Author : huangshengjiang* @Email : 1005542693@qq.com* @Date : 2016-09-21 11:15* @Last Modified Date : 2016-10-19 10:46* @FileName : 尋找多數元素.cpp*//*尋找多數元素.cpp基本概念 : 在數組A[1...n]中,如果有個數值的數量超過[n/2]個,則認為該數值為多數元素,返回該值.否則返回-1觀察結論 : 在數組中刪除任意兩個不同的數值,則原數組中的多數元素在新數組中仍然是多數元素.解決辦法1 : 數組表示,申明一個大小為max(A中最大的數值)的動態數組B[max](需要遍歷A),初始化為0.再對數組A遍歷,在B[A[i]]++;遍歷結束后,B[j]的值就是對應j=A[i]的數量.只要B[j]的值大于n/2下限,則輸出j,否則輸出-1評估1 : 時間復雜度為n*n*max,空間復雜度為max大小的數組.有一個嚴重的缺陷,申請了大量無用的空間max-n.如果max過大n偏小,極大浪費內存,也消耗cpu的功能.解決辦法2 : 鏈表表示,節點結構Node包含三個成員變量,value表示數值,count表示該數值的數量,next是指針,指向下一個Node.遍歷數組A,將A[i]與鏈表從頭到尾進行比較,若找到相應的value值,則count++;如果沒有,則new一個Node,value=A[i],count=1,next = NULL;然后遍歷鏈表,如果鏈表中的節點this->count > n/2,則輸出this->value;否則輸出-1評估2 : 節省了大量數組表示的空間,空間復雜度為different(不同的元素數量)的節點空間.時間復雜度上(按比較次數)為1+2+...+n-1 = n(n-1)/2,為O(n*n),復雜度還是太大.比較排序上可以優化.解決辦法3 : 指針的數組表示int *C[n],將申明n個大小的數組,數組中的元素是指針,初始化指向A[i]對應的地址,也就是建立A[i]元素的索引,對索引進行排序(自底向上排序,基數排序等等),最壞情況下的比較次數為nlogn次,然后在遍歷一遍,對相同的值統計,輸出結果.評估3 : 對索引(C[n])進行交換操作,可以節省大量的實體賦值操作,節省大量的內存資源.(但是這是對于結構大的數據而言效果好,對于int的根本沒必要)解決辦法4 : 直接對數組A進行排序,最壞比較次數為nlogn次,再遍歷一遍A,統計相同的數值的數量,輸出結果評估4 : 統計相同數值的數量,會統計到其他無用的計算,浪費資源.可以直接根據多數元素的定義,直接統計A[n/2]的值的數量解決辦法5 : 在辦法4上進行改進,直接統計A[n/2]的值的數量,兩端用二分法快速找出起始位置和終點位置,相減就是數量,跟n/2比較,輸出結果評估5 : 時間復雜度nlogn+logn,空間復雜度為n解決辦法6 : 不進行排序,直接找出中間元素mid,然后遍歷找出mid的數量評估6 : 時間復雜度為20n+n,更少.解決辦法7 : */ #include <iostream> using namespace std; template<class T> int Size(T &array) {return sizeof(array)/sizeof(array[0]); }//方法1,遍歷數組A,找出多數元素 typedef struct Node {int value;int count;Node * next;Node(int num):value(num),count(1),next(NULL){};Node():value(-1),count(-1),next(0){}; }* headnode,* lnode;class List {headnode head;int n; public:List():n(0){head = new Node();};~List(){deletelist(head);};bool find(int num); void addNode(int num);void increment(int num);int major_return();void deletelist(Node *p); };void List::deletelist(Node *p) {while (p->next){Node *temp = p->next;p->next = temp->next;delete temp;}delete p;}bool List::find(int num) {n++;lnode pre;pre = head;while(pre != NULL && pre->value != num) {pre = pre->next;}if (pre == NULL){return false;}return true; }void List::addNode(int num) {lnode pre = head;lnode newnode = new Node(num);while(pre->next != NULL ) {pre = pre->next;}pre ->next = newnode; }void List::increment(int num) {lnode pre;pre = head;while(pre->value != num) {pre = pre->next;}pre ->count ++; }int List::major_return() {lnode pre;pre = head;int temp = n/2;while(pre != NULL) {if (pre -> count >= temp){return pre ->value;}pre = pre->next;}return -1; }int Majority_first(int *array,int n) {List headlist;int temp = 0;for (int i = 0; i < n; ++i){temp = array[i];if (headlist.find(temp)){headlist.increment(temp);}else{headlist.addNode(temp);}}return headlist.major_return(); }//方法2,刪除數組中任意兩個不同的元素,原數組的多數元素仍是新數組的多數元素 /*分析 : 每次遞歸調用,是先查找原數組中任意不相同的兩個數值(直接與當前數組最后一位進行比較,不同,則將不同的數值與倒數第二位對調,這里不用索引,因為索引指向的類型結構小,不適合)遞歸調用函數的形參表應是數組a,數量n.放回int.遞歸結束標志是1.比較中沒有不相同的數 2.只有一個元素(這種情況包含在1中) (默認有多數元素>n/2的情況下)這種情況得出的結果是候選值,還需要遍歷數組,找出數量.看書分析 : 方法2是每次刪除兩個不同元素.可以進行改進. */ int candidate(int *array,int num) {if (num == 0)return -1;if (num == 1)return array[0];int last = array[num-1];int i = num - 2;for (; i >= 0 ; i-- ){if (array[i] != last)break;}if ( i == -1)return array[0];last = array[num - 2];array[num - 2] = array [i];array[i] = last;return candidate(array,num-2); }//改進candidate,從頭遍歷,如果有一段為平衡數組(候選元素與其他元素數量相同),則從接下來再開始比較,節省遞歸調用的次數 int improve_candidate(int *array ,int num,int start) {int j = start ;int temp = array[start] ;int count = 1;while (j < num && count > 0){j++ ;if (array[j] == temp){count++;}else{count--;}}if ( j == num)return temp;else return improve_candidate(array,num,j+1);}int Majority_second(int *array,int n) {int can = improve_candidate(array,n,1);if (can == -1) return -1;int count = 0 ;for (int i = 0; i < n ; i++){if (array[i] == can){count ++;}}if (count > n/2)return can;return -1; }//測試 int main(int argc, char const *argv[]) {int a[]={1,2,3,4,5,6,7,8,9,1,1,1,1,1,1,1,1};int n=Size(a);int ret = Majority_second(a,n);if (ret == -1){cout << "沒有多數元素";}else{cout << "多數元素為: "<<ret<<endl;}system("pause");return 0; }

轉載于:https://www.cnblogs.com/jiangge3/articles/5981163.html

總結

以上是生活随笔為你收集整理的寻找多数元素的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。