日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

每天一道LeetCode-----二叉搜索树的某两个节点被交换位置,修正这个二叉搜索树

發布時間:2024/4/19 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每天一道LeetCode-----二叉搜索树的某两个节点被交换位置,修正这个二叉搜索树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Recover Binary Search Tree

原題鏈接Recover Binary Search Tree

給定一個二叉搜索樹(BST),但是樹中有兩個節點被交換了,找到這兩個節點,將其修正

二叉搜索樹規則

  • 當前節點的值大于左子樹的所有節點值
  • 當前節點的值小于右子樹的所有節點值
  • 左右子樹同樣是二叉搜索樹

對于二叉搜索樹,如果進行中序遍歷,那么得到的序列一定是遞增的。而對于本題而言,如果使用中序遍歷,那么序列中一定會有兩個值影響到了遞增關系

那么,只需要改變這兩個值的位置,然后重新中序遍歷一遍為所有節點重新賦值即可,空間復雜度為O(n)

代碼如下

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:void recoverTree(TreeNode* root){vector<int> nums;//先中序遍歷把所有節點值找到inOrder(root, nums);//排序,修正節點值順序std::sort(nums.begin(), nums.end());int i = 0;//在中序遍歷一遍,重新為節點賦值recover(root, nums, i);} private:void inOrder(TreeNode* root, vector<int>& nums){if(!root) return;inOrder(root->left, nums);nums.emplace_back(root->val);inOrder(root->right, nums);}void recover(TreeNode* root, vector<int>& nums, int& i){if(!root) return;recover(root->left, nums, i);root->val = nums[i++];recover(root->right, nums, i);} };

當然,為了優化空間復雜度,可以直接在中序遍歷修改節點的值,假設中序遍歷的結果是6,3,4,5,2,可以發現最后應該找到的節點是指向6的和指向2的節點

這兩個節點不滿足遞增關系,因為

  • 6 >= 3,6是第一個節點指向的值
  • 5 >= 2,2是第二個節點指向的值
  • 交換兩個節點指向的值

所以,為了易于比較,需要保存上一個節點,即總共需要三個指針

  • prevNode,保存上一次遍歷的節點
  • firstNode,記錄找到的第一個節點
  • secondNode,記錄找到的第二個節點

不過對于第一個節點,它沒有上一個節點,所以prevNode初始化不應該是nullptr,而是設定一個保存最小整數值的節點,即

TreeNode minNode(INT_MIN); prevNode = &minNode;

至此,只需要在中序遍歷的時候對prevNodefirstNodesecondNode這三個節點進行更新

代碼如下

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/class Solution { public:void recoverTree(TreeNode* root){TreeNode minNode(INT_MIN);//僅僅是為了不用new TreeNode(INT_MIN);prevNode = &minNode;firstNode = secondNode = nullptr;recover(root);swap(firstNode->val, secondNode->val);} private:void recover(TreeNode* root){if(!root) return;recover(root->left);//prevNode記錄上一個節點//當上一個節點的值大于當前節點值時,說明上一個節點是錯誤的,影響了遞增//因為遞增的時候只能大的值跑到前面導致錯誤,所以prevNode是錯誤的if(!firstNode && prevNode->val >= root->val)firstNode = prevNode;//當firstNode記錄完后,當前節點小于前面的節點,說明當前節點是錯誤的//因為遞增的時候只能是小的值跑到后面導致錯誤,所以root是錯誤的if(firstNode && prevNode->val >= root->val)secondNode = root;//改變上一個節點,繼續尋找prevNode = root;recover(root->right);} private:TreeNode* prevNode;TreeNode* firstNode;TreeNode* secondNode; };

本題主要是中序遍歷的問題,解決思路是在中序遍歷中進行更改,兩邊遍歷的方法比較容易想到,但是O(1)的不容易想到

總結

以上是生活随笔為你收集整理的每天一道LeetCode-----二叉搜索树的某两个节点被交换位置,修正这个二叉搜索树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。