zoukankan      html  css  js  c++  java
  • leetcode

    题目: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?

    这道题的意思是本来有一颗BST,但是不小心把其中两个节点互换了,现在需要把这两个节点换回来,或者交换这两个节点的值也行,关键在于找到这两个互换节点

    个人思路:

    1、创建一个vector<TreeNode *> A,保存中序遍历的所有节点,由于原BST有两个节点互换了,那么该中序遍历的结果并不是递增的

    2、再创建一个vector<TreeNode *> B,并用A的元素初始化B,然后为B排序,此时的B是递增顺序的(也即对调了互换节点的指针),遍历比较这两个vector的元素,当发现A的元素不等于B的元素时,表明两个不相等的元素就是那两个互换节点,找到这两个互换节点后,交换它俩的值即可

    代码:

     1 #include <stddef.h>
     2 #include <vector>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 /*
     7 struct TreeNode
     8 {
     9     int val;
    10     TreeNode *left;
    11     TreeNode *right;
    12     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    13 };
    14 */
    15 class Solution
    16 {
    17 public:
    18     void recoverTree(TreeNode *root)
    19     {
    20         vector<TreeNode *> inorderRaw;
    21         inorder(root, inorderRaw);
    22         vector<TreeNode *> inorderSorted(inorderRaw);
    23         sort(inorderSorted.begin(), inorderSorted.end(), Solution::cmp);
    24         vector<TreeNode *>::iterator raw = inorderRaw.begin();
    25         vector<TreeNode *>::iterator sorted = inorderSorted.begin();
    26 
    27         while (true)
    28         {
    29             if ((*raw)->val != (*sorted)->val)
    30             {
    31                 break;
    32             }
    33             ++raw;
    34             ++sorted;
    35         }
    36         int tmp = (*raw)->val;
    37         (*raw)->val = (*sorted)->val;
    38         (*sorted)->val = tmp;
    39     }
    40     static bool cmp(const TreeNode *first, const TreeNode *second)
    41     {
    42         return first->val <= second->val;
    43     }
    44 private:
    45     void inorder(TreeNode *root, vector<TreeNode *> &inorderRaw)
    46     {
    47         if (!root)
    48         {
    49             return;
    50         }
    51         inorder(root->left, inorderRaw);
    52         inorderRaw.push_back(root);
    53         inorder(root->right, inorderRaw);
    54     }
    55 };
    56 /*
    57 int main()
    58 {
    59     return 0;
    60 }
    61 */
    View Code

    题目要求仅使用常数空间,上面的算法不和要求,上网看了几篇文章,找到了符合题意的算法(一开始我也是这么想的,但后来想岔了),链接:http://blog.163.com/ya_mzy/blog/static/19959325520137153340725/

    思路:

    1、这里我们先举个例子来说明,比如一个正常的BST中序遍历应该是递增的,如1234567,现在互换了两个节点3和6,变成1264537

    2、那么,有什么特点呢?当中序遍历时,会有一个节点比后一个节点大,一个节点比前一个节点小,我们就要找到这两个节点,通过预设一个pre指针用于记录中序遍历的前一个节点即可,当这两个互换的节点相邻时,如1243567,仅会有一次当前节点小于前一节点的情况(一般会出现两次,第一次是前一节点,第二次是当前节点),这时这两个节点便是互换节点

    代码:

     1 #include <stddef.h>
     2 
     3 struct TreeNode
     4 {
     5     int val;
     6     TreeNode *left;
     7     TreeNode *right;
     8     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     9 };
    10 
    11 class Solution
    12 {
    13 public:
    14     void recoverTree(TreeNode *root)
    15     {
    16         TreeNode *swappedElement1 = NULL;
    17         TreeNode *swappedElement2 = NULL;
    18         TreeNode *pre = NULL;
    19 
    20         findSwappedElements(root, pre, swappedElement1, swappedElement2);
    21 
    22         int tmp = swappedElement1->val;
    23         swappedElement1->val = swappedElement2->val;
    24         swappedElement2->val = tmp;
    25     }
    26 private:
    27     void findSwappedElements(TreeNode *root, TreeNode *&pre, TreeNode *&swappedElement1, TreeNode *&swappedElement2)
    28     {
    29         if (!root)
    30         {
    31             return;
    32         }
    33 
    34         findSwappedElements(root->left, pre, swappedElement1, swappedElement2);
    35 
    36         if (pre && root->val < pre->val)
    37         {
    38             if (!swappedElement1)
    39             {
    40                 swappedElement1 = pre;
    41                 swappedElement2 = root;
    42             }
    43             else
    44             {
    45                 swappedElement2 = root;
    46             }
    47         }
    48 
    49         pre = root;
    50 
    51         findSwappedElements(root->right, pre, swappedElement1, swappedElement2);
    52     }
    53 };
    54 
    55 int main()
    56 {
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    SQL的各种连接(cross join、inner join、full join)的用法理解
    解决sonarQube 'Unknown': sonar.projectKey
    DOS批处理高级教程
    java自定义注解
    inode备忘
    sed备忘
    awk备忘
    Oracle 删除表中记录 如何释放表及表空间大小
    Oracle 11g 分区拆分与合并
    Maven的settings.xml文件结构之mirrors
  • 原文地址:https://www.cnblogs.com/laihaiteng/p/3803695.html
Copyright © 2011-2022 走看看