面試100題系列之11在樹中找到符合條件的路徑

2021-06-14 01:28:09 字數 1748 閱讀 1647

在二元樹中找出和為某一值的所有路徑(樹),滿足一下要求:

*該路徑是從樹的根節點到葉節點的一條路徑

* 路徑之和恰好等於乙個給定的整數,路徑的定義是節點的data值之和,允許有負數。

* 列印所有滿足條件的路徑

其實這是某公司**面試我的一道題,自己當時答得不是很好,思考一番之後想到了比較完善的解法。可惜面試已經過去了,算了,當做是一種經歷的記錄吧~一共有三種,下面來一一給出。其實就是樹的後序遍歷。

1、作為乙個二逼青年,首先想到的是遞迴吧,好吧,我連二逼青年都不如,因為我當時壓根沒往這方面想啊!!太緊張了,傷不起啊。在這一節,為了後序**更簡潔,也給出一些公共的函式,後面將不會再給了。

#include#includestruct node

;const int n = 30;

node node[n];

node *stack[n];

int top;

int goal;//目標數值

//往二叉查詢樹裡面加節點,公共函式1

void add(node *root, int v)

} else if(root->data > v) }

else

printf("重複加入節點%d\n", v);

}//列印路徑,公共函式2

void print(node **stack, int top)

//遞迴得到路徑

void getpath(node *root, int sum)

else

--top;

}

2、好吧,文藝一點的解法是什麼呢??肯定是用棧來解決啦,但是棧來實現樹的後序遍歷需要flag標記,所以把node的資料結構重新定義一下。

struct node

;//用棧來得到路徑,node的定義中包含flag標記

void getpath(node *root)

if(stack[top]->right == null && sum == goal)//是葉節點並且滿足條件

while(top > -1 && stack[top]->flag)

if(top > -1)

}}

3、更高富帥的版本呢?在節點的定義中加入flag,這就使得定義的資料型別比較大,ok,不加就不加唄!那用什麼方法來標記已經訪問過左子樹的節點呢?用乙個輔助棧就可以啦!輔助棧的棧頂元素對應stack的棧頂元素的訪問情況,下面給出**:

//用輔助棧來標記節點,node節點的定義中不需要flag

void getpathwithstack(node *root)

if(stack[top]->right == null && sum == goal)

while(top > -1 && flagstack[top])

if(top > -1)

}}

4、下面給出各種方法的main函式呼叫,如果不需要的,可以直接pass

int main()

printf("輸入需要查詢的路徑長度:");

scanf("%d",&goal);

//top = -1;//方法1的呼叫

//getpath(&node[0],0);//方法1的呼叫

//getpath(&node[0]);//方法2的呼叫

getpathwithstack(&node[0]);//方法3的呼叫

}}

面試100題系列之18鍊錶合併

碼字也不容易是不?1 給定兩個有序的鍊錶,假設都是 公升序的。需要合併兩個鍊錶,去除重複的元素,也就是求兩個鍊錶的並,這裡要求合併之後的 結果降序排列。既然有序,那問題就簡單多了。ok,輕鬆加愉快的寫出來 遍歷兩個鍊錶,如果鍊錶1的元素比鍊錶2的元素小,取鍊錶1的元素 如果大於,則取鍊錶2的元素 如...

從零單排之微軟面試100題系列 08之反轉鍊錶

本題目選自july大神部落格系列 微軟面試100題 july大神,該系列我主要用來記錄我的學習筆記。題目描述 使用遞迴和不遞迴兩種方法反轉鍊錶。本題亦見於 劍指offer 面試題16 遞迴方法 node reverse node phead 非遞迴方法 因在迭代過程中,鍊錶會出現斷裂,因此需要3個指...

面試100題系列之10關於刪除多餘空格的再思考

題目描述 1 無連續相鄰的兩個空格 2 字串開頭和結尾無空格 3 新的一行開頭和結尾無空格 要得滿分,必須滿足一下兩個條件 a 不能增加新的記憶體空間 b 只能迴圈字串一次 c 不准用庫函式 參考 這樣就可以從檔案中讀入換行符了 include 寫刪除字串中的空格的程式 void main i fr...