LeetCode

时光毁灭记忆、已成空白 提交于 2020-12-16 01:09:38

Topic

  • Tree
  • Depth-first Search

Description

https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/

Given an array 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 array: [-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

Analysis

基本解题思想就是获取数组中位数,再以中位数的下标为界,分成两子数组,递归获取中位数,从而构建一棵BST。

方法一:非递归版,首先获取数组的中位数,然后从root开始DFS,放置合适位置,再以这中位数的下标为界,分成子数组的左右界下标推入栈中,之后形成一循环。

方法二:递归版,方法思想基本与方法一相同。

方法三:别人写的递归版。该方法思想是:首先获取数组的中位数,新建一节点,再以这中位数的下标为界,分为左右子数组,然后节点的左节点则在左子数组中得出,节点的右节点则在右子数组中得出,然后递归获取中位数,从而构建一棵BST。与方法二的区别是,不用从root开始DFS。

方法四:根据方法三思想写的非递归版。

Submission

import java.util.LinkedList;

import com.lun.util.BinaryTree.TreeNode;

public class ConvertSortedArrayToBinarySearchTree {

	// 方法一:非递归版
	public TreeNode sortedArrayToBST1(int[] nums) {
		if (nums == null || nums.length == 0)
			return null;
		int mid = (int) Math.ceil((nums.length - 1) / 2.0);
		TreeNode root = new TreeNode(nums[mid]);
		LinkedList<int[]> stack = new LinkedList<>();
		stack.push(new int[] { mid + 1, nums.length - 1 });
		stack.push(new int[] { 0, mid - 1 });

		while (!stack.isEmpty()) {
			int[] pair = stack.pop();
			int left = pair[0], right = pair[1];
			TreeNode p = root;
			if (left <= right) {
				mid = (int) Math.ceil(left + (right - left) / 2.0);//这样写是为了迎合下面的单元测试用例,普通写法是mid = left + (right - left) / 2
				int temp = nums[mid];

				while (true) {
					if (temp < p.val) {
						if (p.left == null) {
							p.left = new TreeNode(temp);
							break;
						} else {
							p = p.left;
						}
					} else if (temp > p.val) {
						if (p.right == null) {
							p.right = new TreeNode(temp);
							break;
						} else {
							p = p.right;
						}
					} else {
						break;
					}
				}
				stack.push(new int[] { mid + 1, right });
				stack.push(new int[] { left, mid - 1 });
			}
		}

		return root;
	}

	// 方法二:递归版
	public TreeNode sortedArrayToBST2(int[] nums) {
		if (nums == null || nums.length == 0)
			return null;
		int mid = (int) Math.ceil((nums.length - 1) / 2.0);
		TreeNode root = new TreeNode(nums[mid]);
		addNode(nums, root, 0, mid - 1);
		addNode(nums, root, mid + 1, nums.length - 1);
		return root;
	}

	private void addNode(int[] nums, TreeNode root, int left, int right) {
		if (left > right) {
			return;
		}

		int mid = (int) Math.ceil(left + (right - left) / 2.0);
		int temp = nums[mid];
		TreeNode p = root;
		while (true) {
			if (temp < p.val) {
				if (p.left == null) {
					p.left = new TreeNode(temp);
					break;
				} else {
					p = p.left;
				}
			} else if (temp > p.val) {
				if (p.right == null) {
					p.right = new TreeNode(temp);
					break;
				} else {
					p = p.right;
				}
			} else {
				break;
			}
		}
		addNode(nums, root, left, mid - 1);
		addNode(nums, root, mid + 1, right);
	}

	// 方法三:别人写的递归版
	public TreeNode sortedArrayToBST3(int[] num) {
		if (num.length == 0) {
			return null;
		}
		TreeNode head = addNode(num, 0, num.length - 1);
		return head;
	}

	private TreeNode addNode(int[] num, int low, int high) {
		if (low > high) {
			return null;
		}
		int mid = (int) Math.ceil(low + (high - low) / 2.0);
		TreeNode node = new TreeNode(num[mid]);
		node.left = addNode(num, low, mid - 1);
		node.right = addNode(num, mid + 1, high);
		return node;
	}

	// 方法四:根据方法三写成的非递归版
	public TreeNode sortedArrayToBST4(int[] nums) {
		if (nums == null || nums.length == 0)
			return null;
		LinkedList<Object> stack = new LinkedList<>();
		int mid = (int) Math.ceil((nums.length - 1) / 2.0);
		TreeNode root = new TreeNode(nums[mid]);
		TreeNode p = null;

		stack.push(new Object[] { root, 1, mid + 1, nums.length - 1 });
		stack.push(new Object[] { root, 0, 0, mid - 1 });

		while (!stack.isEmpty()) {
			Object[] objs = (Object[]) stack.pop();

			TreeNode parent = (TreeNode) objs[0];
			int leftOrRight = (int) objs[1];
			int low = (int) objs[2];
			int high = (int) objs[3];

			if (low > high)
				continue;

			mid = (int) Math.ceil(low + (high - low) / 2.0);

			if (leftOrRight == 0) {
				p = parent.left = new TreeNode(nums[mid]);
			} else {
				p = parent.right = new TreeNode(nums[mid]);
			}

			stack.push(new Object[] { p, 1, mid + 1, high });
			stack.push(new Object[] { p, 0, low, mid - 1 });
		}

		return root;
	}

}

Test

import static org.junit.Assert.*;
import org.junit.Test;

import com.lun.util.BinaryTree;
import com.lun.util.BinaryTree.TreeNode;

public class ConvertSortedArrayToBinarySearchTreeTest {

	@Test
	public void test() {
		ConvertSortedArrayToBinarySearchTree obj = new ConvertSortedArrayToBinarySearchTree();

		int[] array = {-10, -3, 0, 5, 9};
		
		TreeNode expected = new TreeNode(0);
		
		expected.left = new TreeNode(-3);
		expected.right = new TreeNode(9);
		
		expected.left.left = new TreeNode(-10);
		expected.right.left = new TreeNode(5);
		
		assertTrue(BinaryTree.equals(expected, obj.sortedArrayToBST1(array)));
		assertTrue(BinaryTree.equals(expected, obj.sortedArrayToBST2(array)));
		assertTrue(BinaryTree.equals(expected, obj.sortedArrayToBST3(array)));
		assertTrue(BinaryTree.equals(expected, obj.sortedArrayToBST4(array)));
	}
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!