public IList<IList<int>> LevelOrder(TreeNode root)
        {
            IList<IList<int>> result = new List<IList<int>>();
            if (root == null)
                return result;

            Queue<TreeNode> queue = new Queue<TreeNode>();
            queue.Enqueue(root);
            while (queue.Count > 0)
            {
                IList<int> items = new List<int>();
                int size = queue.Count;
                for (int i = 0; i < size; i++)
                {
                    TreeNode node = queue.Dequeue();
                    items.Add(node.val);

                    if (node.left != null)
                        queue.Enqueue(node.left);
                    if (node.right != null)
                        queue.Enqueue(node.right);
                }
                result.Add(items);
            }
            return result;
        }
        //非递归版本
        /*
         * 对于任一结点P:
         * 1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
         * 2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
         * 3)直到P为NULL并且栈为空则遍历结束
         */
        public IList<int> InorderTraversal2(TreeNode root)
        {
            IList<int> result = new List<int>();
            if (root == null)
                return result;

            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode current = root;
            while (current != null || stack.Count > 0)
            {
                while (current != null)
                {
                    stack.Push(current);
                    current = current.left;
                }

                if (stack.Count > 0)
                {
                    current = stack.Pop();
                    result.Add(current.val);    //访问节点
                    current = current.right;
                }
            }

            return result;
        }
        public bool HasPathSum(TreeNode root, int sum)
        {
            if (root == null)
                return false;

            return dfs(root, root.val, sum);
        }
        private List<TreeNode> generateTrees(int left, int right)
        {
            List<TreeNode> trees = new List<TreeNode>();

            if (left > right)
            {
                trees.Add(null);
                return trees;
            }

            for (int i = left; i <= right; i++)
            {
                List<TreeNode> leftTrees = this.generateTrees(left, i - 1);     //左子树可能性
                List<TreeNode> rightTrees = this.generateTrees(i + 1, right);   //右子树可能性

                //构建以i为根的树
                for (int j = 0; j < leftTrees.Count; j++)
                {
                    for (int k = 0; k < rightTrees.Count; k++)
                    {
                        TreeNode currentTree = new TreeNode(i);
                        currentTree.left = leftTrees[j];
                        currentTree.right = rightTrees[k];

                        trees.Add(currentTree);
                    }
                }
            }
            return trees;
        }
        public void OJ114_FlattenBinaryTreeToLinkedListTest1()
        {
            TreeNode root = new TreeNode(1);
            root.left = new TreeNode(2);
            root.left.left = new TreeNode(3);
            root.left.right = new TreeNode(4);

            root.right = new TreeNode(5);
            root.right.right = new TreeNode(6);

            new OJ114_FlattenBinaryTreeToLinkedList().Flatten(root);

            Assert.AreEqual(1, root.val);

            Assert.AreEqual(null, root.left);
            Assert.AreEqual(2, root.right.val);

            Assert.AreEqual(null, root.right.left);
            Assert.AreEqual(3, root.right.right.val);

            Assert.AreEqual(null, root.right.right.left);
            Assert.AreEqual(4, root.right.right.right.val);

            Assert.AreEqual(null, root.right.right.right.left);
            Assert.AreEqual(5, root.right.right.right.right.val);

            Assert.AreEqual(null, root.right.right.right.right.left);
            Assert.AreEqual(6, root.right.right.right.right.right.val);
        }
        public bool IsSymmetric(TreeNode root)
        {
            if (root == null)
                return true;

            return isSymmetric(root.left, root.right);
        }
 public int MinDepth(TreeNode root)
 {
     if (root == null)
         return 0;
     this.dfs(root, 1);
     return minDepth;
 }
        public IList<IList<int>> ZigzagLevelOrder(TreeNode root)
        {
            IList<IList<int>> result = new List<IList<int>>();
            if (root == null)
                return result;

            Queue<TreeNode> queue = new Queue<TreeNode>();
            queue.Enqueue(root);
            bool isReverse = false;
            while (queue.Count > 0)
            {
                List<int> arr = new List<int>();
                int size = queue.Count;
                for (int i = 0; i < size; i++)
                {
                    TreeNode node = queue.Dequeue();
                    arr.Add(node.val);

                    if (node.left != null)
                        queue.Enqueue(node.left);
                    if (node.right != null)
                        queue.Enqueue(node.right);
                }
                if (isReverse)
                    arr.Reverse();
                isReverse = !isReverse;
                result.Add(arr);
            }
            return result;
        }
        public IList<IList<int>> LevelOrderBottom(TreeNode root)
        {
            IList<IList<int>> result = new List<IList<int>>();
            if (root == null)
                return result;

            Stack<IList<int>> stack = new Stack<IList<int>>();
            Queue<TreeNode> queue = new Queue<TreeNode>();
            queue.Enqueue(root);
            while (queue.Count > 0)
            {
                IList<int> items = new List<int>();
                int num = queue.Count;
                for (int i = 0; i < num; i++)
                {
                    TreeNode node = queue.Dequeue();
                    items.Add(node.val);

                    if (node.left != null)
                        queue.Enqueue(node.left);
                    if (node.right != null)
                        queue.Enqueue(node.right);
                }
                stack.Push(items);
            }

            while (stack.Count > 0)
                result.Add(stack.Pop());

            return result;
        }
 public void OJ129_SumRootToLeafNumbersTest1()
 {
     TreeNode root = new TreeNode(1);
     root.left = new TreeNode(2);
     root.right = new TreeNode(3);
     int sum = new OJ129_SumRootToLeafNumbers().SumNumbers(root);
     Assert.AreEqual(25, sum);
 }
        public void OJ098_ValidateBinarySearchTreeTest2()
        {
            TreeNode root = new TreeNode(1);
            root.right = new TreeNode(1);

            bool result = new OJ098_ValidateBinarySearchTree().IsValidBST(root);
            Assert.AreEqual(false, result);
        }
 public void OJ124_BinaryTreeMaximumPathSumTest1()
 {
     TreeNode tree = new TreeNode(1);
     tree.left = new TreeNode(2);
     tree.right = new TreeNode(3);
     int result = new OJ124_BinaryTreeMaximumPathSum().MaxPathSum(tree);
     Assert.AreEqual(6, result);
 }
        public IList<IList<int>> PathSum(TreeNode root, int sum)
        {
            if (root == null)
                return result;

            this.dfs(root, root.val, new List<int>() { root.val }, sum);
            return result;
        }
 public void OJ094_BinaryTreeInorderTraversalTest1()
 {
     TreeNode tn = new TreeNode(1);
     tn.right = new TreeNode(2);
     tn.right.left = new TreeNode(3);
     IList<int> result = new OJ094_BinaryTreeInorderTraversal().InorderTraversal2(tn);
     ArrayAssert.AreEqual(new int[] { 1, 3, 2 }, result.ToArray());
 }
        public void OJ111_MinimumDepthOfBinaryTreeTest2()
        {
            TreeNode root = new TreeNode(1);
            root.left = new TreeNode(2);

            int result = new OJ111_MinimumDepthOfBinaryTree().MinDepth(root);
            Assert.AreEqual(2, result);
        }
 private void inorderTraversal(TreeNode root, IList<int> result)
 {
     if (root == null)
         return;
     this.inorderTraversal(root.left, result);
     result.Add(root.val);
     this.inorderTraversal(root.right, result);
 }
        public void RecoverTree(TreeNode root)
        {
            this.inOrder(root);

            int temp = p.val;
            p.val = q.val;
            q.val = temp;
        }
        private int getTreeHeight(TreeNode root)
        {
            if (root == null)
                return 0;

            int leftHeight = this.getTreeHeight(root.left);
            int rightHeight = this.getTreeHeight(root.right);
            return Math.Max(leftHeight, rightHeight) + 1;
        }
        public void OJ112_PathSumTest2()
        {
            TreeNode root = new TreeNode(5);
            root.left = new TreeNode(4);
            root.right = new TreeNode(6);

            bool result = new OJ112_PathSum().HasPathSum(root, 9);
            Assert.AreEqual(true, result);
        }
        public void inOrderTraversal(TreeNode node)
        {
            if (node == null)
                return;

            inOrderTraversal(node.left);
            list.Add(node.val);
            inOrderTraversal(node.right);
        }
        public IList<int> InorderTraversal(TreeNode root)
        {
            IList<int> result = new List<int>();
            if (root == null)
                return result;

            inorderTraversal(root, result);
            return result;
        }
        public bool IsSameTree(TreeNode p, TreeNode q)
        {
            if (p == null && q == null)
                return true;
            else if (p == null || q == null)
                return false;

            return p.val == q.val
                && IsSameTree(p.left, q.left)
                && IsSameTree(p.right, q.right);
        }
        private TreeNode generateBST(int[] nums, int left, int right)
        {
            if (left > right)
                return null;

            int mid = (left + right) / 2;
            TreeNode node = new TreeNode(nums[mid]);
            node.left = this.generateBST(nums, left, mid - 1);
            node.right = this.generateBST(nums, mid + 1, right);
            return node;
        }
        public void OJ101_SymmetricTreeTest2()
        {
            TreeNode root = new TreeNode(1);
            root.left = new TreeNode(2);
            root.left.right = new TreeNode(3);
            root.right = new TreeNode(2);
            root.right.right = new TreeNode(3);

            bool result = new OJ101_SymmetricTree().IsSymmetric(root);
            Assert.AreEqual(false, result);
        }
        public void OJ104_MaximumDepthOfBinaryTreeTest1()
        {
            TreeNode root = new TreeNode(3);
            root.left = new TreeNode(9);
            root.right = new TreeNode(20);
            root.right.left = new TreeNode(15);
            root.right.right = new TreeNode(7);

            int result = new OJ104_MaximumDepthOfBinaryTree().MaxDepth(root);
            Assert.AreEqual(3, result);
        }
        public void OJ098_ValidateBinarySearchTreeTest1()
        {
            TreeNode root = new TreeNode(5);
            root.left = new TreeNode(3);
            root.right = new TreeNode(8);
            root.right.left = new TreeNode(6);
            root.right.right = new TreeNode(10);

            bool result = new OJ098_ValidateBinarySearchTree().IsValidBST(root);
            Assert.AreEqual(true, result);
        }
        public void OJ110_BalancedBinaryTreeTest1()
        {
            TreeNode root = new TreeNode(3);
            root.left = new TreeNode(9);
            root.left.left = new TreeNode(9);
            root.right = new TreeNode(20);
            root.right.left = new TreeNode(15);
            root.right.right = new TreeNode(7);

            bool result = new OJ110_BalancedBinaryTree().IsBalanced(root);
            Assert.AreEqual(true, result);
        }
        private bool isSymmetric(TreeNode t1, TreeNode t2)
        {
            if (t1 == null && t2 == null)
                return true;
            else if (t1 == null || t2 == null)
                return false;

            if (t1.val != t2.val)
                return false;

            return isSymmetric(t1.left, t2.right) && isSymmetric(t1.right, t2.left);
        }
        private int dfs(TreeNode node, int sum)
        {
            if (node == null)
                return 0;
            sum = sum * 10 + node.val;
            if (node.left == null && node.right == null)
                return sum;

            int left = dfs(node.left, sum);
            int right = dfs(node.right, sum);
            return left + right;
        }
        private bool dfs(TreeNode root, int currentSum, int resultSum)
        {
            if (root.left == null && root.right == null && currentSum == resultSum)
                return true;

            if (root.left != null && this.dfs(root.left, currentSum + root.left.val, resultSum))
                return true;
            if (root.right != null && this.dfs(root.right, currentSum + root.right.val, resultSum))
                return true;

            return false;
        }