zoukankan      html  css  js  c++  java
  • LIS问题分析

    题目来源,待字闺中,原创@陈利人 ,欢迎大家继续关注微信公众账号“待字闺中”

    原题这个LIS问题,可不是Longest Increasing Subsequence,而是Largest Independent Set,含义例如以下:给定一棵二叉树,找到满足例如以下条件的最大节点集合:集合中的随意两个节点之间,都没有边。例如以下图:


    LIS大小为5,为{10,40,60,70,80}.

    分析:首先还是递归思想,比方对于根节点10,假设把10放入LIS则,20和30不能放入,但它们的孩子40、50、60能够;假设不把10放入,则它的孩子20和30能够,如此可得递归方程式为

    fun(root)=max(fun(root->left)+fun(root->right),1+fun(root->left->left)+fun(root->left->right)+fun(root->right->left)+fun(root->right->right));相同,由于存在反复子问题,因此能够考虑动态规划,可是对于树来说,动态规划须要特殊处理,由于我们没办法从下往上进行处理,这里有一个技巧,我们能够给树节点加入一个标志lis,当该节点没有訪问时lis初始化为0,訪问后lis保存为当前节点的lis集合的大小,从而能够避免反复递归,详细见代码:

    struct BinaryTreeNode
    {
    	int data;
    	int lis;//表示以当前节点为根时lis集合的大小,初始化为0,能够防止反复递归
    	BinaryTreeNode* left;
    	BinaryTreeNode* right;
    	BinaryTreeNode(int val):data(val),lis(0),left(NULL),right(NULL){}
    };
    
    int LIS(BinaryTreeNode* root)
    {
    	if(root == NULL)return 0;
    	if(root->lis)return root->lis;
    	int numNotContainRoot = LIS(root->left)+LIS(root->right);//根节点不增加lis
    	int numContatinRoot = 1;//根节点增加lis
    	if(root->left) numContatinRoot+=LIS(root->left->left)+LIS(root->left->right);
    	if(root->right)numContatinRoot+=LIS(root->right->left)+LIS(root->right->right);
    	root ->lis = max(numNotContainRoot,numContatinRoot);//保存当前根节点所在子树的lis大小
    	return root->lis;
    }

    本代码仅仅代表个人观点,如有错误,请指正,谢谢


  • 相关阅读:
    LCD实验学习笔记(八):中断
    LCD实验学习笔记(七):NAND FLASH
    LCD实验学习笔记(六):存储控制器
    LCD实验学习笔记(五):MMU
    博客已经迁移
    什么是全栈工程师
    深入解析Django Admin模块
    Firefox OS 指导方针-字体
    Firefox OS 指导方针-调色板
    Firefox OS 指导方针-简介
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4284714.html
Copyright © 2011-2022 走看看