降低时间复杂度的几种方法【持续更新】

降低时间复杂度的几种方法【持续更新】

LeetCode的许多题目都对时间复杂度有相应的要求,大家在刷题时遇到一道题可能有自己的解决方法,也确实可行,然而时间复杂度达不到要求也无法通过。这里给大家持续总结LeetCode中遇到的那些降低时间复杂度的方法。

充分利用已有信息(如DP中的备忘录)

LeetCode 652. Find Duplicate Subtrees

Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any one of them.

Two trees are duplicate if they have the same structure with same node values.

Example 1:
1
/
2 3
/ /
4 2 4
/
4
The following are two duplicate subtrees:
2
/
4
and
4
Therefore, you need to return above trees’ root in the form of a list.

字符串的题,找出相同的子树,并返回重复子树的根节点。
  思考:
  1. 除了层序遍历以外,树的遍历就三种——preorder、inorder、postorder。对于找出子树而言,三种遍历选哪一个都可以。
  2. 如果是判断两棵树是否相同,可以采取任一种遍历方式,同步对两棵树进行相同的遍历,并比较每次遍历的值,完全相同即可。(初步想法,low了)
  3.1 题意只要返回重复子树的根节点,联想到初次遍历树时,每次发现一样的节点值,作为一个子树的根节点,跟之前相同的值作为根节点的子树进行比较。选取Map<Integer,TreeNode>数据结构。(每一棵子树只记录根节点进行表示,结果发现复杂度太高,难以实现)
  3.2 既然是相同的子树,那么除了根节点数值相同以外,树的高度也应该相同,那么第一轮遍历记录下①子树根节点的值②子树高度③子树根节点引用 就好了。(每一棵子树记录根节点和子树高度,虽然相比3.1稍好点,但是复杂度依旧很高)
  求助:
  2、3两步都会造成在第1步遍历整棵树后,对已有的信息未充分利用,而是不必要的重复加工,例如已经遍历过的整棵树,在判断各个子树是否相等时,又要把子树全部重新遍历一遍。导致复杂度高
  每一棵子树完整记录,这样比较时就不再需要同时遍历两棵子树了,可以降低比较的复杂度。
  为了降低完整记录时的复杂度,采取如下方案(类似DP中的备忘录):每一棵子树由其子树根节点+左子树+右子树构建而成即可
  代码如下:

    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
   
        Map<String, List<TreeNode>> map = new HashMap<String, List<TreeNode>>();//key存储以每个节点为根节点的子树信息,value存储子树重复的节点
        helper(root,map);
        List<TreeNode> list = new LinkedList<TreeNode>();
        for(List<TreeNode> l:map.values())
            if(l.size() > 1)
                list.add(l.get(0));
        
        // for(Map.Entry<String, List<TreeNode>> entry:map.entrySet())
        //     if(entry.getValue().size() > 1)
        //         list.add(entry.getValue().get(0));        
        return list;
    }
    private String helper(TreeNode root, Map<String, List<TreeNode>> map){
   
        if(root == null)
            return "";
            //充分利用左右子树来构建自己。
        String s = (new Integer(root.val)
  • 7
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值