109. Convert Sorted List to Binary Search Tree

题目描述(中等难度)

在这里插入图片描述
108 题 是一样的,都是给定一个升序序列,然后生成二分平衡查找树。区别在于 108 题给定的是数组,这里给的是链表。

解法一

大家先看一下 108 题 吧,算法的关键是取到中间的数据做为根节点。而这里链表的话,由于不支持随机访问,所以会麻烦些。最简单的思路就是我们把链表先用线性表存起来,然后题目就转换成 108 题了。

为了方便,把上一道题的数组参数改为List 。

import java.util.ArrayList;

class TreeNode{
	int val;
	TreeNode left;
	TreeNode right;
	TreeNode(int x){val=x;}
}
class ListNode{
	int val;
	ListNode next;
	ListNode(int x){val=x;}
}

public class Convert_Sorted_List_to_Binary_Search_Tree {
	
	public static TreeNode sortedListToBST(ListNode head) {
		ArrayList<Integer>nums=new ArrayList<>();
		//将链表用线性表存储起来,转换为108题
		while(head!=null) {
			nums.add(head.val);
			head=head.next;
		}
		return sortedArrayToBST(nums);
	}
	
	public static TreeNode sortedArrayToBST(ArrayList<Integer>nums) {
		return sortedArrayToBST(nums,0,nums.size());
	}
	
	private static TreeNode sortedArrayToBST(ArrayList<Integer>nums,int start,int end) {
		if(start==end) return null;
		
		int mid=(start+end)>>>1;
		TreeNode root=new TreeNode(nums.get(mid));
		root.left=sortedArrayToBST(nums,start,mid);
		root.right=sortedArrayToBST(nums,mid+1,end);
		return root;
	}
	public static void main(String args[]) {
		ListNode head=new ListNode(-10);
		ListNode p=head;
		p.next=new ListNode(-3);
		p=p.next;
		p.next=new ListNode(0);
		p=p.next;
		p.next=new ListNode(5);
		p=p.next;
		p.next=new ListNode(9);
		TreeNode ans=sortedListToBST(head);
		System.out.println(ans.val);
	}
}

时间复杂度:O(log(n))。

空间复杂度:数组进行辅助,O(n)。

解法二

有没有一种方案,不用数组的辅助呢?那么我们需要解决怎么得到 mid 的值的问题。

最直接的思路就是根据 start 和 end,求出 mid,然后从 head 遍历 mid - start 次,就到达了 mid 值。但最开始的 end,我们还得遍历一遍链表才能得到,总体来说就是太复杂了。

这里有一个求中点节点值的技巧,利用快慢指针。

快指针和慢指针同时从头部开始遍历,快指针每次走两步,慢指针每次走一步,当快指针走到链表尾部,此时慢指针就指向了中间位置。

除了求中点节点的值不一样,基本架构和 108 题 是一样的。

public class Convert_Sorted_List_to_Binary_Search_Tree2 {
	
	public TreeNode sortedListToBST(ListNode head) {
		return sortedArrayToBST(head,null);
	}

	private TreeNode sortedArrayToBST(ListNode head, ListNode tail) {
		if(head==tail) return null;
		ListNode fast=head;
		ListNode slow=head;
		
		while(fast!=tail &&fast.next!=tail) {
			slow=slow.next;
			fast=fast.next.next;
		}
		TreeNode root=new TreeNode(slow.val);
		root.left=sortedArrayToBST(head,slow);
		root.right=sortedArrayToBST(slow.next,tail);
		return root;
	}
}

时间复杂度:根据递归式可知,T(n) = 2 * T(n / 2 ) + n,O(nlog(n))。

空间复杂度:O(log(n))。

参考文献

1.https://zhuanlan.zhihu.com/p/74640795
2.https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/discuss/35476/Share-my-JAVA-solution-1ms-very-short-and-concise.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安替-AnTi

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值