这题利用二叉堆维持堆性质的办法来维持Young氏矩阵的性质,题目提示中写得很清楚,不过确实容易转不过弯来。

a,b两问很简单。直接看c小问:

按照Young氏矩阵的性质,最小值肯定在左上角取得,问题在于取出最小值后如何保持矩阵的性质。可以参照max_heapify中的做法,先取出最小值,然后将矩阵左上角置为最大值,这样左上角处的元素必然导致Young氏矩阵的性质违背,于是考虑该元素右边的元素和该元素下边的元素,问题是该与右边元素交换还是与下边元素交换呢?可以发现,如果与T(右)和T(下)中较小的一个元素交换,可以使得另一元素所在的行或列恢复Young氏矩阵性质,这样就把待调整的矩阵的规模减小到了(m - 1) X n 或 m X (n - 1)。递归运行这个过程,直到待调整的矩阵为空,因为每次都将m或n减小1,直到它们都减小到零为止,可知时间复杂度为O(m + n)

d小问实现插入过程,还是参照二叉堆中的插入过程,把新元素插入到矩阵末尾,然后向左上角调整直到到达合适的位置。调整过程的思路其实跟c中的思路类似。这次是与新元素左边元素和上边元素比较。可以发现,如果我把新元素和T(左)、T(上)中较大的元素进行交换,可以使得另一个元素所在的行(或列)恢复Young氏矩阵性质,于是同样把待调整的矩阵规模减小到(m - 1) X n 或m X (n - 1)

e比较直接,extract_min需要线性时间O(n),共有n^2个元素,于是复杂度就是O(n^3)

f问比较难想,我折腾了好久。关键是查找位置是从矩阵的左下角开始。这位置很巧妙,如果k大于它,那它所在的列就不用找了,如果k小于它,那它所在的行就不用找了,也是逐次减小矩阵规模查找元素。

部分实现的源码如下:

#include<iostream>
#include<vector>
using namespace std;
enum class Direction{DOWN, RIGHT, UP, LEFT, OVER};
void extract_helper(vector<vector<int> > &Young, int m, int n){
Direction d = Direction::OVER;
int val = Young[m][n];
if (m + 1 < Young.size() && val > Young[m + 1][n]){
d = Direction::DOWN;
val = Young[m + 1][n];
}
if (n + 1 < Young[0].size() && val > Young[m][n + 1]){
d = Direction::RIGHT;
val = Young[m][n + 1];
}
switch (d){
case Direction::DOWN:
swap(Young[m][n], Young[m + 1][n]);
extract_helper(Young, m + 1, n);
break;
case Direction::RIGHT:
swap(Young[m][n], Young[m][n + 1]);
extract_helper(Young, m, n + 1);
break;
case Direction::OVER:
break;
}
return;
}
int extract_min(vector<vector<int>> &Young){
int min = Young[0][0];
Young[0][0] = INT_MAX;
int m = 0;
int n = 0;
extract_helper(Young, m, n);
return min;
} void insert_helper(vector<vector<int>> &Young, int m, int n){
Direction d = Direction::OVER;
int val = Young[m][n];
if (m - 1 >= 0 && val < Young[m - 1][n]){
val = Young[m - 1][n];
d = Direction::UP;
}
if (n - 1 >= 0 && val < Young[m][n - 1]){
val = Young[m][n - 1];
d = Direction::LEFT;
}
switch (d){
case Direction::UP:
swap(Young[m][n], Young[m - 1][n]);
insert_helper(Young, m - 1, n);
break;
case Direction::LEFT:
swap(Young[m][n], Young[m][n - 1]);
insert_helper(Young, m, n - 1);
break;
case Direction::OVER:
break;
}
}
void insert(vector<vector<int>> &Young, int key){
int M = Young.size();
int N = Young[0].size();
Young[M - 1][N - 1] = key;
int m = M - 1;
int n = N - 1;
insert_helper(Young, m, n);
}
void Young_sort(vector<vector<int>> &Young, vector<int>& result){
while (Young[0][0] != INT_MAX){
int key = extract_min(Young);
result.push_back(key);
}
}

  

算法导论 第六章 思考题6-3 Young氏矩阵的更多相关文章

  1. 算法导论 第六章 思考题 6-3 d叉堆

    d叉堆的实现相对于二叉堆变化不大,首先看它如何用数组表示. 考虑一个索引从1开始的数组,一个结点i最多可以有d个子结点,编号从id - (d - 2) 到 id + 1. 从而可以知道一个结点i的父结 ...

  2. 算法导论 第六章 堆排序(python)

    6.1堆 卫星数据:一个带排序的的数通常是有一个称为记录的数据集组成的,每一个记录有一个关键字key,记录的其他数据称为卫星数据. 原地排序:在排序输入数组时,只有常数个元素被存放到数组以外的空间中去 ...

  3. 算法导论 第六章 2 优先队列(python)

    优先队列:     物理结构: 顺序表(典型的是数组){python用到list}     逻辑结构:似完全二叉树 使用的特点是:动态的排序..排序的元素会增加,减少#和快速排序对比 快速一次排完 增 ...

  4. 《算法导论》第二章demo代码实现(Java版)

    <算法导论>第二章demo代码实现(Java版) 前言 表示晚上心里有些不宁静,所以就写一篇博客,来缓缓.囧 拜读<算法导论>这样的神作,当然要做一些练习啦.除了练习题与思考题 ...

  5. 《算法》第六章部分程序 part 7

    ▶ 书中第六章部分程序,加上自己补充的代码,包括全局最小切分 Stoer-Wagner 算法,最小权值二分图匹配 ● 全局最小切分 Stoer-Wagner 算法 package package01; ...

  6. 《算法》第六章部分程序 part 6

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,包括二分图最大匹配(最小顶点覆盖)的交替路径算法和 HopcroftKarp 算法 ● 二分图最大匹配(最小顶点覆盖)的交替路径算法 package ...

  7. 《算法》第六章部分程序 part 5

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,网络最大流 Ford - Fulkerson 算法,以及用到的流量边类和剩余流量网络类 ● 网络最大流 Ford - Fulkerson 算法 pac ...

  8. 为什么我要放弃javaScript数据结构与算法(第六章)—— 集合

    前面已经学习了数组(列表).栈.队列和链表等顺序数据结构.这一章,我们要学习集合,这是一种不允许值重复的顺序数据结构. 本章可以学习到,如何添加和移除值,如何搜索值是否存在,也可以学习如何进行并集.交 ...

  9. 《算法》第六章部分程序 part 8

    ▶ 书中第六章部分程序,加上自己补充的代码,包括单纯形法求解线性规划问题 ● 单纯形法求解线性规划问题 // 表上作业法,I 为单位阵,y 为对偶变量,z 为目标函数值 // n m 1 // ┌── ...

随机推荐

  1. xml中的xmlns,xmlns:xsi,xsi:schemaLocation有什么作用,如果没有会怎么样呢

    如 maven 的 pom.xml 开头是下面这样的谁能解释下,这东西有社么用,不写这东西又会怎么样的,官方拷贝来的说明文档就算了,我想要简明扼要的说明.不胜感激---------<projec ...

  2. 笔记6:winfrom连接sql server 进行数据交换

    今天的作业是用winfrom窗体做一个留言板,如图: 要求和数据库有查询和添加功能.下拉框里的值是直接获取数据库中的值 一.连接数据库,获取表中数据 //创建一个存数据的表 DataTable tab ...

  3. ajax接触

    1. function doSave() { ajax_get("${contextPath}/auth/functionsave", $("#editForm" ...

  4. 记一次web项目总结

    功能需求,登录,用户管理,新闻管理. 用户管理: // 分页查询所有用户信息 public List<User> userInfo(int index, int pageSize) thr ...

  5. [转]Arrays.sort()你应该知道的事

    以下内容转自: 原文链接: programcreek 翻译: ImportNew.com- 刘志军 译文链接: http://www.importnew.com/8952.html --------- ...

  6. 转 Warning:MongoDB Replica Sets配置注意事项

    我们知道,MongoDB不提供单机的数据安全性,取而代之的是提供了Replica Sets的高可用方案.官方文档中提到的案例是三个节点组成的Replica Sets,这样在其中任何一个节点宕机后都会自 ...

  7. AFNetworking框架使用

    本文是由 iOS Tutorial 小组成员 Scott Sherwood撰写,他是一个基于位置动态加载(Dynamically Loaded)的软件公司(专业的混合定位)的共同创办人. 网络 — 你 ...

  8. POJ 1083 Moving Tables 思路 难度:0

    http://poj.org/problem?id=1083 这道题题意是有若干段线段,每次要求线段不重叠地取,问最少取多少次. 因为这些线段都是必须取的,所以需要让空隙最小 思路: 循环直到线段全部 ...

  9. IT公司100题-7-判断两个链表是否相交

    问题:有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环.1.如何判断一个链表是不是这类链表? 问题扩展:1.如果链表可能有环呢?2.如果需 ...

  10. Section 1.4 Packing Rectangles

    本来是USACO Training的1.4.1的,但是介于今早过了食物链想起了这道题实在是太怨念了,翻出自己写的AC程序居然有5KB!! 思路很简单,枚举,而且就图中的六种情况.但是第六种变化状况太多 ...