Depth-first Search深度优先搜索专题7
834 Sum of Distances in Tree
思路:一顆無向的樹有N個節點,分別標記為0,1,2,…N-1,有若干條邊。結果返回每個節點到其他節點的路徑和。
以上面這棵樹為例。從節點0到其他點的路徑查找過程是:節點0有兩條邊分別到達子節點1和子節點2;遞歸查找節點1(節點1沒有子節點),節點2;繼續查找節點2的子節點…依次下去。遞歸每進一層,路徑就需要加1。
遍歷完節點0以后,再以節點1為根節點,遍歷。
時間復雜度O(N*E),E是邊的數目。這個思路超時。既然是超時,定是因為有重復計算的。例如遍歷邊(0,2),之后又遍歷了一次(2,0)。但是該怎么合并計算,我沒想出來。
學習:接下來的描述,相當于翻譯官方解釋吧。
用一顆新的樹為例子。節點0和節點4是父子關系,也是相鄰節點。現在觀察一下相鄰節點連接后,路徑和發生什么變化。
將節點0和節點4的路徑斷開,得到下圖。
記:stsum[0] 表示節點0在節點0子樹上的路徑和。stsum[4]表示節點4在節點4子樹上的路徑和。count[0]表示節點0子樹的節點數。answer[0]表示節點0在整個樹的路徑和。answer[4]表示節點4在整個樹的路徑和。
當節點0和節點4之間加上路徑后,answer[0]= stsum[0] + stsum[4] + count[4]。因為節點0到節點4子樹上所有點的距離與節點4到節點4子樹上所有點的距離都要加1。answer[4]= stsum[4] + stsum[0] + count[0]。而且能得到answer[0]-answer[4]=count[4]-count[0]。
所以得到結論:相鄰節點(父子節點)x,y在整個樹的路徑和是:answer[x]?answer[y]=count[y]?count[x]answer[x] -answer[y] = count[y] - count[x]answer[x]?answer[y]=count[y]?count[x]。
編碼過程:
1 answer[]存儲以每個節點為根節點在整個樹的路徑和;
2 count[] 存儲以每個節點為根節點的子樹的節點數,初始化每個元素值=1;
3 對某個節點node,dfs后序遍歷,先處理子節點,計算每個子節點y的count和stsum,count[node]+=count[child]count[node]+=count[child]count[node]+=count[child],stsum[node]+=stsum[child]+count[child]stsum[node] +=stsum[child]+count[child]stsum[node]+=stsum[child]+count[child],當遍歷了所有的邊以后answer[node]=stsum[node]answer[node] = stsum[node]answer[node]=stsum[node];如果我們從節點0開始遍歷。這次遍歷結束后只有answer[0]是正確的。其他節點都沒有遍歷完全。
4 再看,上面分析了兩個相鄰節點(父子節點)的路徑和關系。如果有節點parent和子節點child,則有answer[child]=answer[parent]?count[child]+(N?count[child])answer[child] = answer[parent] - count[child] + (N - count[child])answer[child]=answer[parent]?count[child]+(N?count[child]),因為我們已經得到answer[0]的正確結果,可以依據算式計算節點0的子節點的answer。算式中之所以使用count[child]來計算count[parent]:N?count[child])=count[prent]N - count[child])=count[prent]N?count[child])=count[prent],是因為在上一步的后續遍歷過程中,count[parent]的值已經發生變化,不再是parent、child狀態下的count
(原文的解釋是:count[child]從child得到parent比較容易)。用先序遍歷再次遍歷樹,修改每個子節點的answer,得到最終結果。
代碼
301 Remove Invalid Parentheses
思路:最直接的想法:把s中每一個(,)去掉,檢查新的字符串是不是有效字符串,如果是則加入到結果集。
這樣不符合題意的要求:去掉最少的括號。那么需要計算最少去掉幾個左括號,去掉幾個右括號,就可以是有效字符串。
在編碼過程中注意去重。
代碼
學習:可以改進,不再需要判斷是否是有效字符串。添加變量open。有效字符的特征是:左括號在前,所以open>0;左右括號個數相同=>open=0;多余的左右括號都去掉了=>leftCount=0 and rightCount=0。
代碼
總結
以上是生活随笔為你收集整理的Depth-first Search深度优先搜索专题7的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux删除、读取文件原理
- 下一篇: 【五大常用算法】一文搞懂分治算法