這個題目內容是給定兩個非空鏈表,每個鏈表表示一個非負整數,鏈表的每個節點存儲整數的一位,且鏈表頭為最高位,鏈表尾為最低位.求兩個鏈表表示的整數相加后的結果,值也用一個鏈表表示.
例如:
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7
升級版
如果不允許將鏈表翻轉,應該如何解決
我的思路
由于鏈表正向表示一個整數,所以和我們大腦算數的思維方式相同,那就按照直觀的思路去計算,先得到加法結果,然后再將結果優化為題目要求的鏈表即可.
即:
加數: (7 -> 2 -> 4 -> 3 )
被加數: ( 5 -> 6 -> 4 )
初步結果:(7 -> 7 ->10 -> 7 ) // 有進位
化簡后: (7 -> 8 -> 0 -> 7 )
細節思考1
按照我上面舉的例子,有一個默認條件,就是兩個鏈表中假設第一個鏈表長度最長,這樣就可以完全按照例子中的思路來進行處理.但是實際題目給出的鏈表不一定遵循這個規則,所以第一步要計算兩個鏈表的長度,并以最長的鏈表為基礎進行計算,將計算結果存在最長鏈表中,這樣可以在計算初步結果時不用考慮申請新節點問題.
細節思考2
相加的過程不用細說,設較長鏈表長度為 l1,短鏈表長度為 l2.則相加過程為在長鏈表上第(l1-l2)個位置開始,逐個節點計算兩個鏈表每個節點的和,直到最后一個節點.加完就得到了初步結果,然后再進行簡化.應該能看出,這個方法的難點就是在簡化初步結果這里.因為鏈表是正向表示一個整數,而按照進位思路是節點N的下一個節點進位到節點N,但是鏈表又是單向鏈表,只能順序訪問到下個節點,不能訪問到上個節點.
所以,問題來了:如何獲取下一個節點是否需要向前進位,并在本節點上加1.
這個問題,其實還暗含著幾個小的細節,下面我再拆開解釋我的思考過程.
1.獲取下一節點是否需要進位,在當前節點是否加1
這個問題簡單,只有弄兩個指針就好了,第一個指向當前待優化節點,第二個指向下一個節點,用了輔助判斷是否下一位有進位,兩個指針同時像后移動,終止條件是第二個節點等于NULL.
2.進位具有傳遞性
當你判斷下一節點需要進位并在當前節點上面加1的時候,由于進位的傳遞性,有可能出現當前節點在加1操作之后也具有了進位,比如當前節點本來是9,下一節點又需要進位,所以當前節點的值就變成了10,但是此時指針已經指向了這個節點,不能再找到它的上一個節點去加1.所以每一輪優化過程只能保證從尾節點倒數開始的第N節點已經得到化簡,至于整個鏈表中是否都已經完成化簡,并不能確定,只有在進行了 l1次優化過程之后才能完全保證除了頭節點之外的其他節點都已經符合題目要求了.所以這里可以用一個循環對鏈表進行多次優化,來保證整個鏈表都已經得到了化簡.
當然,也可以取個巧,我設置了一個flag,初始化為真,每次循環開始時置為假,然后進行一輪化簡,如果化簡過程中發生了一次進位操作,那就要把flag置為真,以保證再進行一輪化簡,直到一輪化簡下來都沒有進行進位的時候,我就可以認為整個鏈表除頭節點外都已經滿足題目的要求,可以不用進行繼續化簡了,此時flag為假,跳出循環.
3.頭節點的處理
在解決完第2個問題之后,容易發現,我并沒有對頭節點進行化簡,因為如果頭節點要進位的話,還需要申請新節點,這和其他節點的進位操作是不同的,所以我在最后單獨對頭節點進行化簡,如果頭節點需要進位的話就申請一個新節點,然后進行化簡,如果不需要進位則整個步驟完成,直接返回當前頭節點即可.