1、Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [3,2,1]
.
Note: Recursive solution is trivial, could you do it iteratively?
分析:后续遍历二叉树,使用递归方法非常简单,分别递归遍历左子树、右子树,然后打印根结点值;
如果使用非递归遍历,感觉比较复杂,一般想法在首先往左走到最左结点,将前面的结点用栈保存,每次根据栈顶元素,判断该元素右子树是否为空,如果不为空则还得往坐走,还需要判断结点是否遍历过。
最后参考http://blog.csdn.net/wzy_1988/article/details/8450952,最后代码实现中,采用设置一个标志结点为上次输入后续遍历序列中的结点:每次判断栈结点的右孩子是否为标志结点,如果为标志结点说明右子树已经遍历结束,直接弹出该结点;如果右孩子不是标志结点,则说明该结点的右子树没有被遍历,则继续循环,进行右孩子压栈处理。
代码如下:
class Solution { public: vector<int> postorderTraversal(TreeNode *root) { vector<int> postVec; TreeNode* preNode = NULL; TreeNode* tempNode = root; while(tempNode != NULL || !nodeStack.empty()){ if( tempNode != NULL){ //走到左子树的头 nodeStack.push(tempNode); tempNode = tempNode->left; }else{ //如果为空,则遍历右子树 TreeNode* tempRoot = nodeStack.top(); if(tempRoot->right != NULL && tempRoot->right != preNode){ //右结点不为空,且不是刚遍历的结点 tempNode = tempRoot->right; }else{ preNode = nodeStack.top(); //保存上次输出的结果 postVec.push_back(preNode->val); nodeStack.pop(); } } } return postVec; } private: stack<TreeNode*> nodeStack; };
2、Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [1,2,3]
.
Note: Recursive solution is trivial, could you do it iteratively?
分析:使用非递归前序遍历二叉树,已经弄清楚后续遍历了,前序遍历比较简单,只需要用stack保存遍历的结点,访问过的肯定在遍历序列中,不需要关心结点是否遍历过。思路:从根结点开始往左子树走,遇到的结点压栈且插入输出序列,当左孩子为空时,弹栈,往右孩子走一步,再继续上述循环。
代码如下:
class Solution { public: vector<int> preorderTraversal(TreeNode *root) { stack<TreeNode*> nodeStack; vector<int> preVec; while(root != NULL || !nodeStack.empty()){ if(root){ preVec.push_back(root->val); nodeStack.push(root); root = root->left; }else{ root = nodeStack.top(); nodeStack.pop(); root = root->right; } } return preVec; } };
3、Edit Distance
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
分析:求最小编辑距离,这是一个很常见的题目,采用动态规划的方法,借鉴《算法导论》里面求最大公共字串的方法,建立一个矩阵,c[m+1][n+1](其中m,n分别为两个单词的长度),初始化c[0][j]=j,j=0...n,c[i][0]=i,i=0...m;求c[i][j],插入或者删除花费为c[i-1][j]+1和c[i][j-1]+1中的小者,替换花费为如果word1[i]==word2[j],则为c[i-1][j-1],否则为c[i-1][j-1]+1.
代码如下:
class Solution { public: int minDistance(string word1, string word2) { int len1 = word1.length(); int len2 = word2.length(); int** c = new int*[len1+1]; for(int i=0; i<len1+1; ++i){ c[i] = new int[len2+1]; } for(int i=0; i<len1+1;++i){ c[i][0] = i; } for(int j=0; j<len2+1; ++j){ c[0][j] = j; } for(int i=1; i<len1+1;++i){ for(int j=1; j<len2+1; ++j){ int insertCost = min(c[i][j-1],c[i-1][j])+1; int replaceCost = c[i-1][j-1]; if(word1[i-1] != word2[j-1]){ replaceCost += 1; } c[i][j] = min(insertCost,replaceCost); } } int result = c[len1][len2]; for(int i=0; i<len1+1; ++i){ delete[] c[i]; } delete[] c; return result; } };