你算兩個列表的長度。你在開頭填入一個數字爲0的較短列表,以便它們的長度相等。現在你用兩個數字填充一個0(它將被第一個數字的進位所使用,所以有可能9 + 1 = 10)。 您可以創建一個長度等於前兩個的第三個鏈表。
現在你做一類是這樣的:
class Digit
{
public:
Digit *Next;
int Dt;
}
和這樣的功能:
- 這是 「0版本」。
- 在「版本1」中,刪除最後一個進位的額外填充並僅在需要時才添加。
- 在「版本2」中,您從鏈接列表的前面刪除不必要的「0」數字。
- 在「版本3」中,您直接在Sum中創建
runningTotal
鏈接列表。你給第一級總和只是運行總數的「頭」。
- 在「第4版」,而不是填充所述短LL的,則傳遞(這是最困難的流路)的位數從最長LL跳過數的參數。
還有另一種可能性,更復雜,但不需要預先計算列表的長度。它使用兩個遞歸函數:
第一個遞歸函數簡單地橫貫左右,而兩者都存在。如果兩者都在同一時間完成,那麼您可以簡單地按照前面的示例進行回滾。
如果他們中的一個在另一個之前完成,那麼你用另一個這樣的遞歸功能(* extraDigits的初始值爲1):
void SaveRemainingDigits(const Digit *remaining, int *extraDigits, int **buffer)
{
int currentDigit = *extraDigits - 1;
*extraDigits = *extraDigits + 1;
if (remaining->Next)
{
SaveRemainingDigits(remaining->Next, extraDigits, buffer);
}
else
{
*buffer = (int*)malloc(sizeof(int) * extraDigits);
}
(*buffer)[currentDigit] = remaining->Dt;
}
時,這個功能終於返回,我們必須從暫存器在哪裏提取數字和暫存器的長度
我們的第一個遞歸函數的最內層現在已經將最短鏈表的當前數字與暫存器的最後一個數字相加並且放置最長的當前數字在暫存器中代替剛剛使用的數字。現在,您展開遞歸函數,並使用便箋簿作爲圓形數組。展開完成後,將元素添加到RunningTotal鏈接列表中,直接從暫存器中取出它們。
正如我所說,這有點複雜,但在1-2個小時內,我可以把它寫下來作爲一個程序。
一個例子(不進位)
1 2 3 4
6 5
你遞歸前兩個元素。所以你有
1-6 (in the first level)
2-5 (in the second level)
現在你看到,第二個列表已完成,你使用第二個功能。
3 (extraDigit enters as 0, is modified to 1. currentDigit = 0)
4 (extraDigit enters as 1, is modified to 2. currentDigit = 1.
malloc of 2 elements,
buffer[currentDigit] = 4 => buffer[1] = 4)
unroll and we return to the previous row
3 (currentDigit = 0
buffer[currentDigit] = 3 => buffer[0] = 3)
現在我們返回到前一個功能
2-5 (in the second level,
with a lengthBuffer == 2,
we set index = length(buffer) - 1
currentDigitTotal = 5 + buffer[index] => currentDigitTotal = 5 + 4
buffer[index] = 2 => buffer[1] = 2;
index = (index - 1 + lengthBuffer) % lengthBuffer => index = 0
1-6 (in the first level,
with a lengthBuffer == 2,
index = 0,
currentDigitTotal = 6 + buffer[index] => currentDigitTotal = 6 + 3
buffer[index] = 1 => buffer[0] = 1;
index = (index - 1 + lengthBuffer) % lengthBuffer => index = 1
now we exited the recursive function.
In an external function we see that we have a buffer.
We add its elements to the head of the total.
Our Linked list now is 9-9 and our buffer is 1,2 with index 1
for (int i = 0; i < lengthBuffer; i++)
{
runningTotal.AddHead(buffer(index));
index = (index - 1 + lengthBuffer) % lengthBuffer
}
聽起來像一個C問題。爲什麼遞歸??? –
你究竟計算了什麼? l1 [0] + l2 [0] - > l3 [0],還是l1 [0] + l1 [1] + ... - > sum?我真的不明白;) –
這表明你的面試官很愚蠢。以遞歸方式進行遞歸至少與簡單計數列表長度一樣緩慢。他不想直接顛倒列表,而是希望將堆棧用作反向列表。如果你想我可以寫代碼,但在這一點上應該很清楚。 – xanatos