leetcode -day27 Recover Binary Search Tree & Interleaving String

1、


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 s1s2s3, 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;
    }
};


参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

xiao囡囡

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值