前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2022-03-20:给定一棵多叉树的头节点head, 每个节点的颜色只会是0、1、2、3中的一种, 任何两个节点之间的都有路径, 如果节点a和节点b的路径上,

2022-03-20:给定一棵多叉树的头节点head, 每个节点的颜色只会是0、1、2、3中的一种, 任何两个节点之间的都有路径, 如果节点a和节点b的路径上,

原创
作者头像
福大大架构师每日一题
发布2022-03-20 09:47:52
4790
发布2022-03-20 09:47:52
举报
文章被收录于专栏:福大大架构师每日一题

2022-03-20:给定一棵多叉树的头节点head,

每个节点的颜色只会是0、1、2、3中的一种,

任何两个节点之间的都有路径,

如果节点a和节点b的路径上,包含全部的颜色,这条路径算达标路径,

(a -> ... -> b)和(b -> ... -> a)算两条路径。

求多叉树上达标的路径一共有多少?

点的数量 <= 10^5。

答案2022-03-20:

方法一:自然智慧,所有节点两两对比。

方法二:递归,前缀和+后缀和+位运算。目前是最难的。

当前节点是起点,当前节点是终点。

子节点两两对比。

代码用golang编写。代码如下:

代码语言:go
复制
package main

import "fmt"

func main() {
	root := NewNode(0)
	root.nexts = make([]*Node, 2)
	root.nexts[0] = NewNode(1)
	root.nexts[1] = NewNode(2)
	root.nexts[0].nexts = make([]*Node, 1)
	root.nexts[0].nexts[0] = NewNode(3)
	ret := colors3(root)
	fmt.Println(ret)
}

type Node struct {
	color int
	nexts []*Node
}

func NewNode(c int) *Node {
	ans := &Node{}
	ans.color = c
	ans.nexts = make([]*Node, 0)
	return ans
}

type Info struct {
	// 我这棵子树,总共合法的路径有多少?
	all int
	// 课上没有强调!但是请务必注意!
	// 一定要从头节点出发的情况下!
	// 一定要从头节点出发的情况下!
	// 一定要从头节点出发的情况下!
	// 走出来每种状态路径的条数
	colors []int
}

func NewInfo() *Info {
	ans := &Info{}
	ans.all = 0
	ans.colors = make([]int, 16)
	return ans
}

func colors3(head *Node) int {
	if head == nil {
		return 0
	}
	return process3(head).all
}

var consider = [][]int{{}, // 0
	{14, 15},                       // 1 -> 0001
	{13, 15},                       // 2 -> 0010
	{12, 13, 14, 15},               // 3 -> 0011
	{11, 15},                       // 4 -> 0100
	{10, 11, 14, 15},               // 5 -> 0101
	{9, 11, 13, 15},                // 6 -> 0110
	{8, 9, 10, 11, 12, 13, 14, 15}, // 7 -> 0111
	{7, 15},                        // 8 -> 1000
	{6, 7, 14, 15},                 // 9 -> 1001
	{5, 7, 13, 15},                 // 10 -> 1010
	{4, 5, 6, 7, 12, 13, 14, 15},   // 11 -> 1011
	{3, 7, 11, 15},                 // 12 -> 1100
	{2, 3, 6, 7, 10, 11, 14, 15},   // 13 -> 1101
	{1, 3, 5, 7, 9, 11, 13, 15},    // 14 -> 1110
	{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, // 15 -> 1111
}

func process3(h *Node) *Info {
	ans := NewInfo()
	hs := 1 << h.color
	ans.colors[hs] = 1
	if len(h.nexts) > 0 {
		n := len(h.nexts)
		infos := make([]*Info, n+1)
		for i := 1; i <= n; i++ {
			infos[i] = process3(h.nexts[i-1])
			ans.all += infos[i].all
		}

		lefts := make([][]int, n+2)
		for i := 0; i < n+2; i++ {
			lefts[i] = make([]int, 16)
		}
		for i := 1; i <= n; i++ {
			for status := 1; status < 16; status++ {
				lefts[i][status] = lefts[i-1][status] + infos[i].colors[status]
			}
		}

		rights := make([][]int, n+2)
		for i := 0; i < n+2; i++ {
			rights[i] = make([]int, 16)
		}
		for i := n; i >= 1; i-- {
			for status := 1; status < 16; status++ {
				rights[i][status] = rights[i+1][status] + infos[i].colors[status]
			}
		}
		for status := 1; status < 16; status++ {
			ans.colors[status|hs] += rights[1][status]
		}
		ans.all += ans.colors[15] << 1
		for from := 1; from <= n; from++ {
			for fromStatus := 1; fromStatus < 16; fromStatus++ {
				for _, toStatus := range consider[fromStatus|hs] {
					ans.all += infos[from].colors[fromStatus] * (lefts[from-1][toStatus] + rights[from+1][toStatus])
				}
			}
		}
	}
	return ans
}

执行结果如下:

在这里插入图片描述
在这里插入图片描述

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档