如何計算每次擊碎磚塊而消失的磚塊數量
和頂部相連的磚塊不會掉落;
擊碎乙個磚塊,可能使得其它與之連線的磚塊不再與頂部相連而消失;
消失的磚塊數量 = 擊碎之前與頂部相連的磚塊數量 - 擊碎之後與頂部相連的磚塊數量 - 1 (1就是直接被敲碎的那塊磚)
並查集的按秩優化的秩即可以指當前子樹的高度rank,也可以指當前集合的結點總數size,此題按size優化很huochi
如何使用並查集解決這個問題?
消除乙個磚塊的效果是:乙個連通分量被分成了兩個連通分量;
並查集的作用是:把兩個連通分量合併成乙個連通分量;
所以我們需要關心,補上乙個擊碎的磚塊,會有多少磚塊因為這個補上的磚塊而重新與屋頂相連。我們按照hits陣列的逆序依次補上磚塊即可。
class
unionfind
}int
findf
(int x)
return f[x];}
void
merge
(int x,
int y)
intgetsize
(int x)};
class
solution
;int addy[4]
=;vectorint>>
copy
(rows, vector<
int>
(cols));
for(
int i =
0; i < rows;
++i)
}// 第一步,把grid中的磚頭全部擊碎
for(
int i =
0; i < hits.
size()
;++i)
// 第二步,建圖,把磚塊的連線情況輸入並查集,構建連通分量
int gridsize = rows * cols;
unionfind unionfind
(gridsize +1)
;//還要加上表示屋頂的乙個點,即rows * cols
// 先把第一行的頂點連到屋頂
for(
int j =
0; j < cols;
++j)
}// 將copy中其它相連的點構成乙個個連通分量
for(
int i =
1; i < rows;
++i)
if(j >
0&& copy[i]
[j -1]
==1)}
}}// 第三步,按照hits陣列的逆序補回磚塊
int hitslength = hits.
size()
; vector<
int>
result
(hitslength)
;for
(int i = hitslength -
1; i >=0;
--i)
for(
int j =
0; j <
4; j++)}
}int current = unionfind.
getsize
(gridsize)
; result[i]
=max(0
, current - origin -1)
; copy[x]
[y]=1;
// 真正地補回磚塊
}return result;}}
;
每日一題 LeetCode
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。示例 1 輸入 7,5,6,4 輸出 5 限制 0 陣列長度 50000 思想是 分治演算法 所有的 逆序對 於 3 個部分 左邊區間的逆序對 右邊區間的逆序對 橫跨兩個區間的...
LeetCode每日一題(題1028)
最近在刷leetcode每日一題,每次做完之後總能有些收穫,所以想著不如每天寫個部落格記錄一下做的題目的解法以及自己寫的時候問題出在 從先序遍歷還原二叉樹 題目大意 給出乙個字串 1 2 3 4 5 6 7 1代表節點的值,前面的 個數代表節點的深度。如果只有乙個子節點,保證這個節點為左子節點。返回...
LeetCode每日一題(題139)
題目 題目大意 給出乙個字串s和乙個字串陣列words,判斷s是否能夠拆分成多個words中的字串。分析 這道題比較簡單的方式應該是採用動態規劃來做。對於任意乙個字串中的區間,可以判斷該區間組成的字串是否在字典中,如果是,則這個區間的真假取決於前面那個區間的真假。給出狀態轉移方程dp i dp j ...