【树】B013_将有序链表转换为二叉搜索树(分治思想 | 快慢指针)

一、题目描述

Given a singly linked list where elements are sorted in ascending order, 
convert it to a height balanced BST.

For this problem, a height-balanced binary tree is defined as a binary tree 
in which the depth of the two subtrees of every node never differ by more than 1.

Example:
Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
      0
     / \
   -3   9
   /   /
 -10  5

二、题解

方法一:将将链表转换为数组

方法和将有序数组转化为二叉搜索树是一样的,采用分治思想,不断压缩区间。

public TreeNode sortedListToBST(ListNode head) {
   List<Integer> nums = new ArrayList<>();
   while (head != null) {
       nums.add(head.val);
       head = head.next;
   }
   return dfs(nums, 0, nums.size());
}
TreeNode dfs(List<Integer> nums, int l, int r) {
   if (l == r) {
       return null;
   }
   int mid = (l + r) >>> 1;
   TreeNode root = new TreeNode(nums.get(mid));
   root.left =  dfs(nums, l, mid);
   root.right = dfs(nums, mid+1, r);
   return root;
}

复杂度分析

  • 时间复杂度: O ( n ) O(n)
  • 空间复杂度: O ( n ) O(n)

方法二:寻找链表的中间结点

核心逻辑:寻找链表的中心结点。然后递归构造二叉搜索树。

  • slow 走 1 步,fast 走两步,fast 为空时,slow 就到达链表的中心了。
public TreeNode sortedListToBST(ListNode head) {
  if (head == null)
      return null;
  return dfs(head, null);
}
private TreeNode dfs(ListNode l, ListNode r) {
  if (l == r)
      return null;
  ListNode slow = l;
  ListNode fast = l;
  while (fast != r && fast.next != r) {
    slow = slow.next;
    fast = fast.next.next;
  }
  TreeNode root = new TreeNode(slow.val);
  root.left = dfs(l, slow);
  root.right = dfs(slow.next, r);
  return root;
}

复杂度分析

  • 时间复杂度: O ( n l o g n ) O(n logn) ,对于链表的 n 个结点,都需要 log(n) 时间去寻找它的中心节点。
  • 空间复杂度: O ( l o g n ) O(log n) ,二叉搜索树的高度为 l o g ( n ) log(n)
发布了495 篇原创文章 · 获赞 105 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/104856695