LeetCode - Easy - 530. Minimum Absolute Difference in BST

Topic

  • Tree

Description

https://leetcode.com/problems/minimum-absolute-difference-in-bst/

Given the root of a Binary Search Tree (BST), return the minimum absolute difference between the values of any two different nodes in the tree.

Example 1:

Input: root = [4,2,6,1,3]
Output: 1

Example 2:

Input: root = [1,0,48,null,null,12,49]
Output: 1

Constraints:

  • The number of nodes in the tree is in the range [ 2 , 1 0 4 ] [2, 10^4] [2,104].
  • 0 < = N o d e . v a l < = 1 0 5 0 <= Node.val <= 10^5 0<=Node.val<=105

Analysis

方法一:中续遍历模式递归

方法二:前后续遍历模式递归

Submission

import java.util.Stack;

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

public class MinimumAbsoluteDifferenceInBST {
	
	//方法一:中续遍历模式递归
	public int getMinimumDifference3(TreeNode root) {
    	int[] min = {Integer.MAX_VALUE};
    	Integer[] prev = {null};
    	getMinimumDifference3(root, min, prev);
    	return min[0];
	}
	
	private void getMinimumDifference3(TreeNode node, int[] min, Integer[] prev) {
    	if(node == null) return;
    	getMinimumDifference3(node.left, min, prev);
    	if(prev[0] != null)
    		min[0] = Math.min(min[0], node.val - prev[0]);
    	prev[0] = node.val;
    	getMinimumDifference3(node.right, min, prev);
	}

	//方法二:前后续遍历模式递归
	public int getMinimumDifference4(TreeNode root) {
    	int min = Integer.MAX_VALUE;
    	if(root == null) return min;
    	
    	TreeNode lp = root.left;
    	if(lp != null) {//查左子树最大值节点
    		while(lp.right != null) {
    			lp = lp.right;
    		}
    		
    		min = Math.min(min, root.val - lp.val);
    	}
    	
    	TreeNode rp = root.right;
    	if(rp != null) {//查右子树最小值节点
    		while(rp.left != null) {
    			rp = rp.left;
    		}
    		
    		min = Math.min(min, rp.val - root.val);
    	}
    	
    	min = Math.min(Math.min(min, getMinimumDifference4(root.left)), // 
    			getMinimumDifference4(root.right));
    	
        return min;
	}
	
	
	//以下为旧版本回答,保留记录
	
    public int getMinimumDifference(TreeNode root) {
    	
    	//There are at least two nodes in this BST.
    	boolean throwException = false;
    	if(root == null) {
    		throwException = true;
    	}else {
    		if(root.left == null && root.right == null) {
    			throwException = true;
    		}
    	}
    	if(throwException) {
    		throw new IllegalArgumentException();
    	}
    	
    	//正戏
    	int min = Integer.MAX_VALUE;
    	
    	Stack<TreeNode> stack = new Stack<>();
    	
    	while(true) {
    		if(root.left == null && root.right == null) {
    			if(stack.isEmpty()) {
    				break;
    			}else {
    				root = stack.pop();
    			}
    		}else if(root.left != null && root.right == null){
    			min = Math.min(getMinAbsDiff(root), min);
    			root = root.left;
    		}else if(root.left == null && root.right != null){
    			min = Math.min(getMinAbsDiff(root), min);
    			root = root.right;
    		}else {
    			min = Math.min(getMinAbsDiff(root), min);
    			stack.push(root.right);
    			root = root.left;
    		}
    	}
    	
        return min;
    }
    
    
    private int getMinAbsDiff(TreeNode p) {
    	
    	int a = p.val; 
    	Integer	leftDiff = null, rightDiff = null;
    	
    	TreeNode leftMaxNode = BinaryTree.max(p.left);
    	TreeNode rightMinNode = BinaryTree.min(p.right);
    	
    	if(leftMaxNode != null) {
    		leftDiff = Math.abs(a - leftMaxNode.val);
    	}
    	
    	if(rightMinNode != null) {
    		rightDiff = Math.abs(a - rightMinNode.val);
    	}
    	
    	
    	if(leftDiff != null && rightDiff == null) {
    		return leftDiff;
    	}

    	if(leftDiff == null && rightDiff != null) {
    		return rightDiff;
    	}
    	
    	return Math.min(leftDiff, rightDiff);
    	
    }
    
    //
    
    int minDiff = Integer.MAX_VALUE;
    TreeNode prev;
    
    /**
     * 
     * <p>Since this is a BST, the inorder traversal of its nodes results in a sorted list of values. <strong>Thus, the minimum absolute difference must occur in any adjacently traversed nodes.</strong> I use the global variable "prev" to keep track of each node's inorder predecessor.</p>
     * 
     * <p>
     * 例如:输入的二叉树<br>
     *root->600<br>
	 *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/  \<br>
	 *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;424  612<br>
	 *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\   /<br>
	 *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;499 689<br>
     * </p>
     * 
     * <p>中序遍历后得 424 499 600 612 689 ,得出一个升序的数列。显然,最小值绝对差就由两个相邻的数的出。</p>
     * 
     * @param root
     * @return
     */
    public int getMinimumDifference2(TreeNode root) {
        inorder(root);
        return minDiff;
    }
    
    public void inorder(TreeNode root) {
        if (root == null) return;
        inorder(root.left);
        if (prev != null) 
        	minDiff = Math.min(minDiff, root.val - prev.val);
        prev = root;
        inorder(root.right);
    }

}

Test

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

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


public class MinimumAbsoluteDifferenceInBSTTest {
	
	@Test
	public void test() {
		MinimumAbsoluteDifferenceInBST mad =  new MinimumAbsoluteDifferenceInBST();
		TreeNode root = BinaryTree.integerArray2BinarySearchTree(new int[] {1, 3, 2});
		assertEquals(1, mad.getMinimumDifference(root));
		assertEquals(1, mad.getMinimumDifference2(root));
		assertEquals(1, mad.getMinimumDifference3(root));
		assertEquals(1, mad.getMinimumDifference4(root));
	}
	
	@Test
	public void test4() {
		MinimumAbsoluteDifferenceInBST mad = new MinimumAbsoluteDifferenceInBST();
		TreeNode root = BinaryTree.integerArray2BinarySearchTree(new int[] {236,104,701,227,911});
		assertEquals(9, mad.getMinimumDifference(root));
		assertEquals(9, mad.getMinimumDifference2(root));
		assertEquals(9, mad.getMinimumDifference3(root));
		assertEquals(9, mad.getMinimumDifference4(root));
	}
	@Test
	public void test5() {
		MinimumAbsoluteDifferenceInBST mad = new MinimumAbsoluteDifferenceInBST();
		TreeNode root = BinaryTree.integerArray2BinarySearchTree(new int[] {600,424,612,499,689});
		assertEquals(12, mad.getMinimumDifference(root));
		assertEquals(12, mad.getMinimumDifference2(root));
		assertEquals(12, mad.getMinimumDifference3(root));
		assertEquals(12, mad.getMinimumDifference4(root));
	}
	
	@Test(expected=IllegalArgumentException.class)
	public void test2() {
		MinimumAbsoluteDifferenceInBST mad = new MinimumAbsoluteDifferenceInBST();
		TreeNode root = BinaryTree.integerArray2BinarySearchTree(new int[] {1});
		mad.getMinimumDifference(root);
		//assertEquals(1, mad.getMinimumDifference(root));
	}
	
	@Test(expected=IllegalArgumentException.class)
	public void test3() {
		MinimumAbsoluteDifferenceInBST mad = new MinimumAbsoluteDifferenceInBST();
		TreeNode root = null;
		mad.getMinimumDifference(root);
		//assertEquals(1, mad.getMinimumDifference(root));
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值