算法题——Convert Sorted List to Binary Search Tree(JAVA)

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

读题:
1.列表是递增排序的
2.高度平衡的二叉树

知识储备:
BST(二叉搜索树)
1. 所有非叶子结点至多拥有两个儿子(left和right)
2. 所有结点存储一个关键字;
3. 非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树

解题思路:
1.将数组的中间元素作为根节点,比他小的值放在left,比他大的值放在right,分成两部分后,将新的子节点视为根节点,依次递归。

遇到的问题:
当用以下代码提交时,出现了超时的问题,在执行一个数据量很大的测试用例,时间为9ms

if (begin <= end){
    ///执行语句
}  else {
    return null;
}

当修改了return null的位置后

if (begin <= end){
    ///执行语句
}
return null;

执行时间变为7ms

一点小小的变化却在时间复杂度上造成了不小的影响。
根据查到的资料:
如果基本操作就是比较,那么一条if 语句的计数为1
如果比较不是基本操作,相对基本操作,比较的时间可以忽略,那么只需要对基本操作计数
if 语句中,不执行基本操作的不计数,执行的计数。

虽然大部分人在计算时间复杂度时,并没有留意这一点点时间,然而事实表明还是有差别的,那这个差别到底在哪呢?
我认为这要从汇编语言的原理上讲,
在多分支结构中,if/else采用cmp xxx,1 jnz xxx、cmp xxx,2 jnz xxx、cmp xxx,3 jnz xxx…的方式实现的。
因此第1段代码在执行if语句时,首先执行判断,若不符合条件,则跳转到下一条else的位置继续执行return null语句。
与第2段代码相比,执行判断后,若不符合条件,则结束if语句,再顺序执行return null语句。
因此二者的区别应是在于第1段代码多了一个跳转指令,所以多了少许的执行时间。

提交代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }

 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        HashMap<Integer,TreeNode> map = new HashMap<Integer,TreeNode>();
        int count = 0;
        ListNode i = head;
        while (i != null) {
            map.put(count, new TreeNode(i.val));
            i = i.next;
            count++;
        }
        return buildT(map,0,count-1);
    }

    public TreeNode buildT(HashMap<Integer,TreeNode> map, int begin, int end) {
        if (begin <= end){
            int mid = (begin + end) / 2;
            TreeNode t = map.get(mid);
            t.left = buildT(map,begin,mid-1);
            t.right = buildT(map,mid+1,end);
            return t;
        }
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值