Young氏矩阵

m*n的Young氏矩阵定义如下:

  1. m*n的矩阵
  2. 每一行,每一列的数据有序
  3. ∞表示不存在的元素

如:

 2    3    5   12

 4    8  14    

 9  16   ∞     

 ∞   ∞   ∞     

 

1. 如何在O(m+n)时间复杂度的条件下实现删除最小元素,并使删除后的矩阵保持为Young氏矩阵?

将矩阵类比成“二叉树”:某一元素下边的元素类比为该元素的左孩子,右边的元素类比为右孩子,则Young氏矩阵可看成一个小根堆。

因此,可参考堆排序中的EXTRACT_MIN算法来实现。

为表达方便,以A[i, j]表示以A[i, j]为左上角边界的矩阵,如A[1, 2]为:

  3   5   12

  8  14   

 16  ∞    

  ∞   ∞  

首先,需要实现MIN_HEAPIFY。当A[i+1, j]以及A[i, j+1]均为Young氏矩阵时,使以A[i, j]也为Young氏矩阵,伪代码如下:

 1 MIN_HEAPIFY(A, i, j)
 2     min_i = i
 3     min_j = j
 4     if i + 1 <= m && A[i+1][j] < A[i][j]
 5         min_i = i + 1
 6         min_j = j
 7     if j + 1 <= n &&  A[i][j+1] < A[min_i][min_j]
 8         min_i = i
 9         min_j = j + 1
10     if min_i != i || min_j != j
11         exchange A[i][j] <-> A[min_i][min_j]
12         MIN_HEAPIFY(A, min_i, min_j)

EXTRACT_MIN实现伪代码如下:

1 EXTRACT_MIN(A)
2     x <- A[1, 1]
3     A[1, 1] = A[last_element_i][last_element_j]
4     A[last_element_i][last_element_j] =5     MIN_HEAPIFY(A, 1, 1)
6     return x

其中last_element_i 与last_element_j满足:与右下角元素距离最小的非∞元素

确定last_element_i与last_element_j的伪代码如下:

1 GET_LAST_ELEMENT(A, last_element_i, last_element_j)
2     for s <- m + n - 1 to 2
3         for i <- m to 1
4             if 1 <= s - i <= m
5                 j = s - i
6                 if A[i][j] !=7                     last_element_i = i
8                     last_element_j = j
9                     return

 

2. 在O(m+n)时间内,将一个新元素插入到一个未满的m*n Young氏矩阵中

首先找到与右下角元素距离“最远”的∞元素,将GET_LAST_ELEMENT算法稍作修改即可。其次执行DECREASE_KEY操作,伪代码如下:

 1 DECREASE_KEY(A, i, j, key)
 2     while i >= 1 and j >= 1
 3         max_i = i
 4         max_j = j
 5         A[i][j] = key
 6         if i - 1 >= 1 and A[i-1][j] > key
 7             max_i = i - 1
 8             max_j = j
 9         if j - 1 >= 1 and A[i][j-1] > A[max_i][max_j]
10             max_i = i
11             max_j = j - 1
12         if max_i != i or max_j != j
13             A[i][j] = A[max_i][max_j]
14             i = max_i
15             j = max_j
16             A[i][j] = key
17         else
18             A[i][j] = key
19             return

 

3.在O(m+n)时间内,确定一个给定的数是否存在于一个给定m*n的Young氏矩阵

注意到Young氏矩阵右上角元素的特性:该元素大于其左边的同行元素,小于其下边的同列元素。因此,每次用矩阵右上角元素与给定元素比较时,若右上角元素小于给定元素,则可剔除这一行;同理,可剔除这一列。每次比较均可剔除一行或一列,因此,可在O(m+n)的时间内完成任务。

伪代码如下:

1 FIND_ELEMENT(A, i, j, key)
2     if i > m or j < 1
3         return -1
4     else if A[i][j] == key
5         return (i, j)
6     else if A[i][j] < key
7         return FIND_ELEMENT(A, i + 1, j, key)
8     else
9         return FIND_ELEMENT(A, i, j - 1, key)
posted @ 2012-11-08 17:05  zzwab  阅读(350)  评论(0编辑  收藏  举报