您的位置:首页 > 其它

[算法分析与设计] leetcode 每周一题: 554. Brick Wall

2017-12-13 16:40 337 查看
题目链接: 

554. Brick Wall


题目大意:

( 注: leetcode 的原题页面有示例及示意图 )

给定一堵墙 wall, wall 分若干行, 每一行等高, 但每行可能由不同数量, 不同宽度的 brick(s) 组成 ; 求出自墙顶向下的一条垂直的路径, 使路径经过的 brick 尽可能少, 其中, 若路径经过两块 brick 之间 (故墙的左右两条边不算),
则视为 其穿透而过, 即此时路径经过的 brick 数为 0 ;

wall 用 二维数组 表示, 其中 wall 的元素表示 各行, 各 行 的元素表示 行内的 brick (从左往右) 各自的宽度 ; 返回 最理想的路径所经过的 brick 的数目 ;

( 具体还是看原题所附的示例 )

解题过程:

(1) 一开始我直接对 每一条可能的路径 记录 其所经过的砖块的数量,
也即, 以 半块砖 为步进, 忽略 两砖之间的夹缝, 不断将每一列 +1, 从而最后找出 值最小的那一列 即可 ;

(2) 显然, 当存在宽度很大的砖块时, 会做极多的重复劳动, 最后超时 ... ;

(3) 然后打算以 段(segment) 的方式 作记录, 最后作相应统计处理, 但实现到一半发现会有点麻烦, 转而考虑其他思路 ;

(4) 然后可以发现, 可以反过来记录 夹缝 的位置和数量 (而非 要经过的砖块), 因为 只有位于同一列的 夹缝 可以同时被 该列对应的路径 利用 ;

(5) 而 最后的结果 则显然就只需要用 墙的行数 减去 夹缝最多的某一列上的夹缝数 即可 ;

(*) 为确定 "列" 的位置, 可以先将各砖块的位置固定下来
(如: 用各砖块离墙左端的距离 而不是 其各自的顺序和宽度 来统一区分) ;

代码如下:

class Solution {
public:
int leastBricks(vector<vector<int>>& wall) {
auto rows = wall;
unordered_map< size_t, int > goodCols;
for (auto & row : rows) {
for (size_t i = 1; i < row.size(); i++) {
goodCols[ row[i-1] ]++;
row[i] += row[i-1];
}
}

if (goodCols.empty()) {
return rows.size();
}
auto most = max_element(
goodCols.begin(),
goodCols.end(),
[&](pair<size_t, int> a, pair<size_t, int> b) {
return a.second < b.second;
}
)->second;
auto ret = rows.size() - most;
return ret;
}
};
(*) max/min_element 函数 在输入的容器为空时返回的是 end迭代器 ... ;

Runtime: 42 ms

题目链接: 

554. Brick Wall


题目大意:

( 注: leetcode 的原题页面有示例及示意图 )

给定一堵墙 wall, wall 分若干行, 每一行等高, 但每行可能由不同数量, 不同宽度的 brick(s) 组成 ; 求出自墙顶向下的一条垂直的路径, 使路径经过的 brick 尽可能少, 其中, 若路径经过两块 brick 之间 (故墙的左右两条边不算),
则视为 其穿透而过, 即此时路径经过的 brick 数为 0 ;

wall 用 二维数组 表示, 其中 wall 的元素表示 各行, 各 行 的元素表示 行内的 brick (从左往右) 各自的宽度 ; 返回 最理想的路径所经过的 brick 的数目 ;

( 具体还是看原题所附的示例 )

解题过程:

(1) 一开始我直接对 每一条可能的路径 记录 其所经过的砖块的数量,
也即, 以 半块砖 为步进, 忽略 两砖之间的夹缝, 不断将每一列 +1, 从而最后找出 值最小的那一列 即可 ;

(2) 显然, 当存在宽度很大的砖块时, 会做极多的重复劳动, 最后超时 ... ;

(3) 然后打算以 段(segment) 的方式 作记录, 最后作相应统计处理, 但实现到一半发现会有点麻烦, 转而考虑其他思路 ;

(4) 然后可以发现, 可以反过来记录 夹缝 的位置和数量 (而非 要经过的砖块), 因为 只有位于同一列的 夹缝 可以同时被 该列对应的路径 利用 ;

(5) 而 最后的结果 则显然就只需要用 墙的行数 减去 夹缝最多的某一列上的夹缝数 即可 ;

(*) 为确定 "列" 的位置, 可以先将各砖块的位置固定下来
(如: 用各砖块离墙左端的距离 而不是 其各自的顺序和宽度 来统一区分) ;

代码如下:

class Solution {
public:
int leastBricks(vector<vector<int>>& wall) {
auto rows = wall;
unordered_map< size_t, int > goodCols;
for (auto & row : rows) {
for (size_t i = 1; i < row.size(); i++) {
goodCols[ row[i-1] ]++;
row[i] += row[i-1];
}
}

if (goodCols.empty()) {
return rows.size();
}
auto most = max_element(
goodCols.begin(),
goodCols.end(),
[&](pair<size_t, int> a, pair<size_t, int> b) {
return a.second < b.second;
}
)->second;
auto ret = rows.size() - most;
return ret;
}
};
(*) max/min_element 函数 在输入的容器为空时返回的是 end迭代器 ... ;

Runtime: 42 ms
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: