// 面试题34:二叉树中和为某一值的路径 // 题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所 // 有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 #include <cstdio> #include "BinaryTree.h" #include <vector> void FindPath(BinaryTreeNode* pRoot, int expectedSum, std::vector<int>& path, int& currentSum); void FindPath(BinaryTreeNode* pRoot, int expectedSum) { if (pRoot == nullptr || expectedSum <= 0) return; std::vector<int> path; int currentSum = 0; FindPath(pRoot, expectedSum, path, currentSum); } void FindPath ( BinaryTreeNode* pRoot, int expectedSum, std::vector<int>& path, int& currentSum ) { //当前节点加入路径 path.push_back(pRoot->m_nValue); currentSum += pRoot->m_nValue; //如果当前节点为叶节点, 且当前和和预期一致, 打印路径 if (pRoot->m_pLeft == nullptr && pRoot->m_pRight == nullptr && currentSum == expectedSum) { printf("A path is found: "); std::vector<int>::iterator iter = path.begin(); for (; iter != path.end(); ++iter) printf("%d ", *iter); printf(" "); } //存在左右节点 if (pRoot->m_pLeft) FindPath(pRoot->m_pLeft, expectedSum, path, currentSum); if (pRoot->m_pRight) FindPath(pRoot->m_pRight, expectedSum, path, currentSum); //返回时删除掉此节点 currentSum -= pRoot->m_nValue; path.pop_back(); }
// ====================测试代码==================== void Test(const char* testName, BinaryTreeNode* pRoot, int expectedSum) { if (testName != nullptr) printf("%s begins: ", testName); FindPath(pRoot, expectedSum); printf(" "); } // 10 // / // 5 12 // / // 4 7 // 有两条路径上的结点和为22 void Test1() { BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7); ConnectTreeNodes(pNode10, pNode5, pNode12); ConnectTreeNodes(pNode5, pNode4, pNode7); printf("Two paths should be found in Test1. "); Test("Test1", pNode10, 22); DestroyTree(pNode10); } // 10 // / // 5 12 // / // 4 7 // 没有路径上的结点和为15 void Test2() { BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7); ConnectTreeNodes(pNode10, pNode5, pNode12); ConnectTreeNodes(pNode5, pNode4, pNode7); printf("No paths should be found in Test2. "); Test("Test2", pNode10, 15); DestroyTree(pNode10); } // 5 // / // 4 // / // 3 // / // 2 // / // 1 // 有一条路径上面的结点和为15 void Test3() { BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); ConnectTreeNodes(pNode5, pNode4, nullptr); ConnectTreeNodes(pNode4, pNode3, nullptr); ConnectTreeNodes(pNode3, pNode2, nullptr); ConnectTreeNodes(pNode2, pNode1, nullptr); printf("One path should be found in Test3. "); Test("Test3", pNode5, 15); DestroyTree(pNode5); } // 1 // // 2 // // 3 // // 4 // // 5 // 没有路径上面的结点和为16 void Test4() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNode1, nullptr, pNode2); ConnectTreeNodes(pNode2, nullptr, pNode3); ConnectTreeNodes(pNode3, nullptr, pNode4); ConnectTreeNodes(pNode4, nullptr, pNode5); printf("No paths should be found in Test4. "); Test("Test4", pNode1, 16); DestroyTree(pNode1); } // 树中只有1个结点 void Test5() { BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1); printf("One path should be found in Test5. "); Test("Test5", pNode1, 1); DestroyTree(pNode1); } // 树中没有结点 void Test6() { printf("No paths should be found in Test6. "); Test("Test6", nullptr, 0); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); return 0; }
分析:递归思想。
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { vector<vector<int> > printPath; if (root == nullptr || expectNumber <= 0) return printPath; vector<int> path; int currentSum = 0; return FindPath(root, path, printPath, expectNumber, currentSum); } vector<vector<int> > FindPath( TreeNode* root, vector<int>& path, vector<vector<int> >& printPath, int expectNumber, int currentSum) { currentSum += root->val; path.push_back(root->val); if (root->left == nullptr && root->right == nullptr && currentSum == expectNumber) { vector<int> printTemp; vector<int>::iterator iter = path.begin(); for (; iter != path.end(); ++iter) { printTemp.push_back(*iter); } printPath.push_back(printTemp); } if (root->left) FindPath(root->left, path, printPath, expectNumber, currentSum); if (root->right) FindPath(root->right, path, printPath, expectNumber, currentSum); currentSum -= root->val; path.pop_back(); return printPath; } };