零 標題:演算法(leetode,附思維導圖 + 全部解法)300題之(2125)銀行中的鐳射束數量
一 題目描述
二 解法總覽(思維導圖)
三 全部解法
1 方案1
1)程式碼:
// 方案1 “直接計數 - 模擬法”。
// 思路:
// 1)狀態初始化:map存放每一層存放 安全裝置 的情況。
// 2)核心1:遍歷 bank 的每一層。
// 2.1)遍歷當前層的每一列。
// 2.1.1)若 i層的j列 為 安全裝置,則 通過map、對 相應的值進行 +1 操作。
// 3)核心2:2層遍歷。
// 3.1)若 當前i、j 層均存在安全裝置 且 介於(i, j)層 均無安全裝置,
// 則 resCount += (map.get(i) * map.get(j)) 。
// 4)返回結果 resCount 。
var numberOfBeams = function(bank) {
// isValid方法:介於 top、bottom 均沒有安全裝置,說明是 “合法的”。
const isValid = (top, bottom, map) => {
let resBool = true;
for (let i = top + 1; i < bottom; i++) {
if (map.get(i)) {
resBool = false;
break;
}
}
return resBool;
};
// 1)狀態初始化:map存放每一層存放 安全裝置 的情況。
const l = bank.length;
let map = new Map(),
resCount = 0;
// 2)核心1:遍歷 bank 的每一層。
for (let i = 0; i < l; i++) {
const tempStr = bank[i],
tempStrLength = tempStr.length;
// 2.1)遍歷當前層的每一列。
for (let j = 0; j < tempStrLength; j++) {
// 2.1.1)若 i層的j列 為 安全裝置,則 通過map、對 相應的值進行 +1 操作。
if (tempStr[j] === '1') {
if (map.has(i)) {
map.set(i, map.get(i) + 1);
}
else {
map.set(i, 1);
}
}
}
}
// 3)核心2:2層遍歷。
for (let i = 0; i < l; i++) {
for (let j = i + 1; j < l; j++) {
// 3.1)若 當前i、j 層均存在安全裝置 且 介於(i, j)層 均無安全裝置,
// 則 resCount += (map.get(i) * map.get(j)) 。
if (map.get(i) && map.get(j) && isValid(i, j, map)) {
resCount += (map.get(i) * map.get(j));
}
}
}
// 4)返回結果 resCount 。
return resCount;
};
2 方案2
1)程式碼:
// 方案2 “簡約的1次遍歷法”。
// 思路:
// 1)狀態初始化:pre = 0, resCount = 0 。
// 2)核心1:從 [0, l-1] 遍歷 bank 的每一層 。
// 2.1)獲得當前 i層 的安全裝置個數。
// 2.2)若 當前 i層 的安全裝置個數 大於 0,則 resCount += pre * cur; pre = cur 。
// 3)返回結果 resCount 。
var numberOfBeams = function(bank) {
// getCountByLevel方法:獲取 bank的level層 的安全裝置個數。
const getCountByLevel = (level) => {
const tempStr = bank[level],
tempStrLength = tempStr.length;
let resNum = 0;
for (let i = 0; i < tempStrLength; i++) {
if (tempStr[i] === '1') {
resNum++;
}
}
return resNum;
};
// 1)狀態初始化:pre = 0, resCount = 0 。
const l = bank.length;
let pre = 0,
resCount = 0;
// 2)核心:從 [0, l-1] 遍歷 bank 的每一層 。
for (let i = 0 ; i < l; i++) {
// 2.1)獲得當前 i層 的安全裝置個數。
const cur = getCountByLevel(i);
// 2.2)若 當前 i層 的安全裝置個數 大於 0,則 resCount += pre * cur; pre = cur 。
if (cur > 0) {
resCount += pre * cur;
pre = cur;
}
}
// 3)返回結果 resCount 。
return resCount;
}
3 方案3
1)程式碼:
// 方案3 “4行程式碼(因為有4個分號) - 裝X法”。
// n個元素 變成 1個元素 ---> 優先考慮陣列的 reduce 方法。
// 思路:
// 1)通過 陣列的 map 方法,計算 bank的每層安全裝置個數 —— 依次存放入陣列(“假定其名為 tempList ”)中,
// 2)通過 陣列的 reduce 方法,不斷根據 當前層的安全裝置個數(cur)、更新 當前鐳射束的總數量(acc) 並返回 。
var numberOfBeams = function(bank) {
let pre = 0;
return bank.map(item => item.split('').filter(itemInner => itemInner === '1').length)
.reduce((acc, cur) => {
if (cur > 0) {
// 注:這1行 等同於 下面2行程式碼。
[acc, pre] = [acc + (pre * cur), cur];
// acc += pre * cur;
// pre = cur;
}
return acc;
}, 0);
}
四 資源分享 & 更多
1 歷史文章 - 總覽
2 博主簡介
碼農三少 ,一個致力於編寫 極簡、但齊全題解(演算法) 的博主。
專注於 一題多解、結構化思維 ,歡迎一起刷穿 LeetCode ~