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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

young氏矩阵

發布時間:2024/9/30 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 young氏矩阵 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.jobcoding.com/array/matrix/young-tableau-problem/

如果一個矩陣每一行每一列都嚴格單調遞增,我們稱該矩陣為楊氏矩陣(Young Tableau)。對于楊氏矩陣(a[m][ n]),通常會涉及兩個問題:(1) 怎樣在楊氏矩陣中查找某個元素X?(2) 怎樣在楊氏矩陣找第k大的數?


2. 解決方案

楊氏矩陣是一種非常巧妙的數據結構,它既可以用來當堆,又可以用來當做平衡樹。

(1) 問題1求解

【方案一】

<二分查找>

對于楊氏矩陣,由于每行每列均是有序的,則可以于矩陣采用二分查找。具體方法是:

對于當前子矩陣a[i][j]~a[s][t],中間元素為a[(i+s)/2][(j+t)/2],如果a[(i+s)/2][(j+t)/2]==x,則找出該元素;如果a[(i+s)/2][(j+t)/2] > x,則在子矩陣a[i][j]~a[(i+s)/2][(j+t)/2]中查找;如果a[(i+s)/2][(j+t)/2] < x,則在三個子矩陣:a[i][(j+t)/2]~ a[(i+s)/2][t],a[(i+s)/2][(j+t)/2]~ a[s][t]和a[(i+s)/2][j]~ a[s][ (j+t)/2]中查找。該算法的遞歸式為f(mn)=3f(mn/4)+O(1),根據主定理知,時間復雜度為:O((mn)^(log4(3)))。

【方案二】

<類堆查找法>

楊氏矩陣具有明顯的堆特征:從矩陣的右上角出發(從左下角出發思路類似),對于元素a[i][j],如果a[i][j]==x,則找到元素x,直接返回;如果a[i][j] > x,則向下移動,即繼續比較a[i+1][j]與x;如果a[i][j]<x,則向左移動,即繼續比較a[i][j-1]與x。該算法的時間復雜度是O(m+n),代碼如下:

bool find_in_YoungTableau(int** a, int m, int n, int x) {assert(a != NULL && m > 0 && n > 0);int row, col;row = 0;col = n-1;while(row <= m-1 && col >= 0) {if(a[row][col] == x)return true;else if(a[row][col] > x)col--;elserow++;}return false; }

(2) 問題2求解

【方案一】

<小頂堆法>

首先將a[0][0]加入小頂堆,然后每次從小頂堆中取出最小元素,并加入比該元素大且與之相鄰的兩個元素(對于a[0][0],則需要加入a[0][1]和a[1][0]),直到取出第k個元素,需要注意的是,需要采用額外空間記錄某個元素是否已經加入到小頂堆以防止重復加入。

【方案二】

<二分枚舉+類堆查找>

首先,二分枚舉找到一個數x,它比楊氏矩陣中k個數大;然后,利用類堆查找法找到剛好小于x的元素。該算法的時間復雜度為O((m+n)lg(mn)),但不需要額外存儲空間。代碼如下:



int find_kth_in_YoungTableau(int** a, int m, int n, int k) {int low = a[0][0];int high = a[m-1][n-1];int order = 0;int mid = 0;do {mid = (low + high) >> 1;order = get_order(a, m, n, mid);if(order == k)break;else if(order > k)high = mid - 1;elselow = mid + 1;} while(1); //二分枚舉整,找出正好大于k的一個整數 mid int row = 0;int col = n - 1;int ret = mid;while(row <= m-1 && col >= 0) { //找出比mid小的最大數if(a[row][col] < mid) {ret = (a[row][col] > ret) ? a[row][col] : ret;row++;} else {col--;}}return ret; }//整數k在矩陣中的排名 int get_order(int** a, int m, int n, int k) {int row, col, order;row = 0;col = n-1;order = 0;while(row <= m-1 && col >= 0) {if(a[row][col] < k) {order += col + 1;row++;} else {col--;}}return order; }



總結

以上是生活随笔為你收集整理的young氏矩阵的全部內容,希望文章能夠幫你解決所遇到的問題。

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