Recover Binary Search Tree
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
分析:搜索二叉树 有两个节点交换了要求换回来,直观感觉中序遍历节点,得到顺序表,如果没有出错应该是从小到大排列,找出不符合的结点交换值即可。但是题目要求空间复杂度为常数级,考虑用一个结点保存中序遍历的前一结点,保存当前结点,按中序遍历的方法,如果前一结点值大于当前结点值则出错结点为前一结点或者当前结点,如果出错结点1为空则,前一结点为出错结点1,当前结点为出错结点2,如果出错结点1非空,则当前结点为出错结点2,一直遍历到结束,交换两个出错结点的值即可。
class Solution {
public:
TreeNode* preNode;
TreeNode* node1;
TreeNode* node2;
void recoverTree(TreeNode *root) {
preNode = NULL;
node1 = NULL;
node2 = NULL;
recursiveTree(root);
if(node1 && node2){
int temp = node1->val;
node1->val = node2->val;
node2->val = temp;
}
}
void recursiveTree(TreeNode *root){
if(!root){
return;
}
if(root->left){
recursiveTree(root->left);
}
if(preNode && root->val < preNode->val){
if(node1){
node2 = root;
}else{
node1 = preNode;
node2 = root;
}
}
preNode = root;
if(root->right){
recursiveTree(root->right);
}
}
};
2、Interleaving String
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc"
,
s2 = "dbbca"
,
When s3 = "aadbbcbcac"
, return true.
When s3 = "aadbbbaccc"
, return false.
分析:判断一个字符串是否是两个字符串交叉得到的,想到组合字符串的每个字符与s1和s2一个个比较,但是这样有个问题,当字符与两个字符串的字符都相同时与哪个比较,还有回溯问题很难;利用动态规划,这个也不好想,建立一个(s1.size()+1)*(s2.size+2)的表格,表格中坐标为(i,j)处的值表示为s1的前i-1个字符和s2的前j-1个字符能否得到s3的前(i+j-1)个字符,这样最后得到的(s1.size(),s2.size())处的布尔值则为答案,注意初始化时f[0][0] = true, i=0或者j=0时,初始化判断f[i-1][0]是否为true并且s1[i] == s3[i],j=0时同理;表格上的递推式为f[i][j] = (f[i-1][j]&&s1[i-1]==s3[i+j-1]) || (f[i][j-1]&&s2[j-1]==s3[i+j-1])。
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
bool **f = new bool*[s1.size()+1];
for(int i=0; i<=s1.size(); ++i){
f[i] = new bool[s2.size()+1];
}
if (s1.size() + s2.size() != s3.size())
return false;
f[0][0] = true;
for(int i = 1; i <= s1.size(); i++)
f[i][0] = f[i-1][0] && (s3[i-1] == s1[i-1]);
for(int j = 1; j <= s2.size(); j++)
f[0][j] = f[0][j-1] && (s3[j-1] == s2[j-1]);
for(int i = 1; i <= s1.size(); i++)
for(int j = 1; j <= s2.size(); j++)
f[i][j] = (f[i][j-1] && s2[j-1] == s3[i+j-1]) || (f[i-1][j] && s1[i-1] == s3[i+j-1]);
bool result = f[s1.size()][s2.size()];
for(int i=0; i<=s1.size(); ++i){
delete[] f[i];
}
delete[] f;
return result;
}
};