在二元樹中找出和為某一值的所有路徑(樹),滿足一下要求:
*該路徑是從樹的根節點到葉節點的一條路徑
* 路徑之和恰好等於乙個給定的整數,路徑的定義是節點的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...