二叉树单色路径最长&&穿珠子

Posted 小河沟大河沟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树单色路径最长&&穿珠子相关的知识,希望对你有一定的参考价值。

对树的操作,特别理解递归的好处。

//对于一棵由黑白点组成的二叉树,我们需要找到其中最长的单色简单路径,其中简单路径的定义是从树上的某点开始沿树边走不重复的点到树上的
//另一点结束而形成的路径,而路径的长度就是经过的点的数量(包括起点和终点)。而这里我们所说的单色路径自然就是只经过一种颜色的点的路径。
//你需要找到这棵树上最长的单色路径。
//给定一棵二叉树的根节点(树的点数小于等于300,请做到O(n)的复杂度),请返回最长单色路径的长度。
//这里的节点颜色由点上的权值表示,权值为1的是黑点,为0的是白点。


//这题用动态规划来求解。需要用到一对引用传值(white和black)来记录每个节点的左右孩子节点的黑白路径长度值传递上来。
//如:lhswhite ,lhsblack ,rhswhite,rhsblack分别表示两个孩子节点的黑白最长路径长度
//分两类情况:
//(1)当父节点为黑时:其white = 0,black = max(lhsblack + 1, rhsblack + 1),它的最长单色路径长度为lhsblack + rhsblack + 1;
//(2)当父节点为白时:其black = 0,white = max(lhswhite + 1, rhswhite + 1),它的最长单色路径长度为lhswhite + rhswhite + 1;

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
        val(x), left(nullptr), right(nullptr) {
    }
};
//也不知道为什么就是不AC,和下面的有区别吗????
class LongestPath {
public:
    int result = 0;
    
    int findPath(TreeNode* root) {
        // write code here
        if (root==nullptr)
        {
            return 0;
        }
        int white = 0, black = 0;
        path(root,white,black);
        return result;
    }
    void path(TreeNode* root, int &white, int &balck)
    {
        if (root->right == nullptr&&root->right == nullptr)
        {
            if (root->val == 1)
            {
                balck = 1; white = 0;
            }
            else
            {
                balck = 0; white = 1;
            }
        }
        else
        {
            int lblack = 0, lwhite = 0;
            int rblack = 0, rwhite = 0;
            if (root->right != nullptr)
            {
                path(root->right, rwhite, rblack);
            }
            if (root->left != nullptr)
            {
                path(root->left, lwhite, lblack);
            }
            if (root->val == 1)
            {
                if (lblack + rblack + 1 > result)
                    result = lblack + rblack + 1;
                white = 0;
                balck = (lblack + 1) > (rblack + 1) ? (lblack + 1) : (rblack + 1);
            }
            else
            {
                if (rwhite + lwhite + 1 > result)
                    result = rwhite + lwhite + 1;
                balck = 0;
                white = (lwhite + 1) > (rwhite + 1) ? (lwhite + 1) : (rwhite + 1);
            }
        }
    }
};

class LongestPath {
public:
    int ret = 0;
    int findPath(TreeNode* root) {
        // write code here
        int white = 0, black = 0;
        dfsPath(root, white, black);
        return ret;
    }
    void dfsPath(TreeNode* root, int &white, int &black){
        if (root->left == nullptr && root->right == nullptr){
            if (root->val == 1){
                white = 0; black = 1;
            }
            else{
                white = 1; black = 0;
            }
        }
        else{
            int lhswhite = 0, lhsblack = 0;
            int rhswhite = 0, rhsblack = 0;
            if (root->left != nullptr) dfsPath(root->left, lhswhite, lhsblack);
            if (root->right != nullptr) dfsPath(root->right, rhswhite, rhsblack);
            if (root->val == 1){
                if (lhsblack + rhsblack + 1 > ret) ret = lhsblack + rhsblack + 1;
                white = 0;
                black = lhsblack + 1 > rhsblack + 1 ? lhsblack + 1 : rhsblack + 1;
            }
            else{
                if (lhswhite + rhswhite + 1 > ret) ret = lhswhite + rhswhite + 1;
                black = 0;
                white = lhswhite + 1 > rhswhite + 1 ? lhswhite + 1 : rhswhite + 1;
            }
        }
    }
};

参考:http://www.cnblogs.com/chenhuan001/p/5420368.html。找规律!

//现在A和B在玩一个游戏,这个游戏首先给了他们很多珠子,珠子有两种颜色,一种蓝色,一种黄色,我们假定两种珠子都有无限多。
//A需要选择n颗珠子(n为奇数),然后由B串成一串项链(顺序由B确定, 这里的项链也就是一个环)。假如在最后串成的项链中,
//A能够找到两个不同位置的蓝色珠子,并在这两处把这个项链断开成两段,其中一段恰好长度为(n + 1) / 2那么A就胜利了,
//注意这里为整数截断除法且这个长度是不包括选出的两颗珠子的。现在请你计算出A至少要选择多少颗蓝色珠子,才能保证无论B怎么串,
//他都能获胜。举个例子,当A选了7颗珠子,其中有3颗蓝珠子,那么如果B串的项链为"蓝蓝红红红红蓝",则A能获胜,
//若B串的项链为"蓝蓝红红蓝红红",则A不能获胜。
//
//输入描述 :
//给定一个整数n,为A要选出的珠子颗数.
//
//
//输出描述 :
//     请返回A至少要选的蓝珠子颗数。
//
// 输入例子 :
//7
//
//输出例子 :
//     4

class Chain {
public:
    int findK(int n) {
        // write code here
        if (n % 3 == 0) return n / 2;
        else return (n + 1) / 2;
    }
};

 

以上是关于二叉树单色路径最长&&穿珠子的主要内容,如果未能解决你的问题,请参考以下文章

使用C在搜索二叉树中查找最长路径

剑指offer-二叉树的深度

剑指offer-二叉树的深度

剑指offer-二叉树的深度

华为OD机试真题Java实现数组二叉树真题+解题思路+代码(2022&2023)

二叉树-路径(前序)