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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[Leetcode][第99题][JAVA][恢复二叉搜索树][中序遍历]

發布時間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leetcode][第99题][JAVA][恢复二叉搜索树][中序遍历] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】[困難]

【解答思路】

1. 顯示中序遍歷

時間復雜度:O(N) 空間復雜度:O(N)

class Solution {public void recoverTree(TreeNode root) {List<Integer> nums = new ArrayList<Integer>();inorder(root, nums);int[] swapped = findTwoSwapped(nums);recover(root, 2, swapped[0], swapped[1]);}public void inorder(TreeNode root, List<Integer> nums) {if (root == null) {return;}inorder(root.left, nums);nums.add(root.val);inorder(root.right, nums);}public int[] findTwoSwapped(List<Integer> nums) {int n = nums.size();//第一次找到取前面 第二次找到取后面int x = -1, y = -1;for (int i = 0; i < n - 1; ++i) {if (nums.get(i + 1) < nums.get(i)) {y = nums.get(i + 1);if (x == -1) {x = nums.get(i);} else {break;}}}return new int[]{x, y};}public void recover(TreeNode root, int count, int x, int y) {if (root != null) {if (root.val == x || root.val == y) {root.val = root.val == x ? y : x;if (--count == 0) {return;}}recover(root.right, count, x, y);recover(root.left, count, x, y);}} }
2. 隱式中序遍歷 棧


時間復雜度:O(N) 空間復雜度:O(H)

class Solution {public void recoverTree(TreeNode root) {Deque<TreeNode> stack = new ArrayDeque<TreeNode>();TreeNode x = null, y = null, pred = null;while (!stack.isEmpty() || root != null) {while (root != null) {stack.push(root);root = root.left;}root = stack.pop();if (pred != null && root.val < pred.val) {y = root;if (x == null) {x = pred;} else {break;}}pred = root;root = root.right;}swap(x, y);}public void swap(TreeNode x, TreeNode y) {int tmp = x.val;x.val = y.val;y.val = tmp;} }
3. Morris 中序遍歷





時間復雜度:O(N) 空間復雜度:O(1)

class Solution {public void recoverTree(TreeNode root) {TreeNode x = null, y = null, pred = null, predecessor = null;while (root != null) {if (root.left != null) {// predecessor 節點就是當前 root 節點向左走一步,然后一直向右走至無法走為止predecessor = root.left;while (predecessor.right != null && predecessor.right != root) {predecessor = predecessor.right;}// 讓 predecessor 的右指針指向 root,繼續遍歷左子樹if (predecessor.right == null) {predecessor.right = root;root = root.left;}// 說明左子樹已經訪問完了,我們需要斷開鏈接else {if (pred != null && root.val < pred.val) {y = root;if (x == null) {x = pred;}}pred = root;predecessor.right = null;root = root.right;}}// 如果沒有左孩子,則直接訪問右孩子else {if (pred != null && root.val < pred.val) {y = root;if (x == null) {x = pred;}}pred = root;root = root.right;}}swap(x, y);}public void swap(TreeNode x, TreeNode y) {int tmp = x.val;x.val = y.val;y.val = tmp;} }

【總結】

1. 交換的思想

兩個指針或兩個標志找逆序

2. 二叉搜索樹 中序遍歷 單調遞增
3.空間復雜度優化 Morris 中序遍歷優化 空間復雜度:O(1)

轉載鏈接:https://leetcode-cn.com/problems/recover-binary-search-tree/solution/hui-fu-er-cha-sou-suo-shu-by-leetcode-solution/

總結

以上是生活随笔為你收集整理的[Leetcode][第99题][JAVA][恢复二叉搜索树][中序遍历]的全部內容,希望文章能夠幫你解決所遇到的問題。

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