我刚刚研究了一些谷歌面试问题,我在网上偶然发现了一个我似乎无法理解的问题
考虑具有N个节点的无向树,编号从1到N.每个节点都有一个与之关联的标签,这是一个整数值。不同的节点可以具有相同的标签。编写一个函数,给定长度为N的零索引数组A,其中A [j]是树中第(j + 1)节点的标签值,以及长度为K =(N)的零索引数组E. - 1)* 2描述树的边缘,返回最长路径的长度,使得该路径上的所有节点具有相同的标签。长度是该路径中的边数。
示例:
A = [1,1,1,2,2] E = [1,2,1,3,2,4,2,5]
此树如下所示。节点遵循表单标签值。
----------1, 1
-----1, 2 1, 3
2, 4 2, 5
该函数应返回2,因为最长的路径是2→1> 3,并且此路径中有2条边。
假设1 <= N <= 1000并且阵列A的每个元素是[1,1000000000]范围内的整数。
你有什么打算解决这个问题?谢谢!
答案 0 :(得分:1)
这是我的建议。我没有彻底检查过它。
from collections import defaultdict
A = [1, 1, 1, 2, 2]
E = [1, 2, 1, 3, 2, 4, 2, 5]
d = defaultdict(list)
it = iter(E)
for k, v in zip(it, it):
d[k].append(v)
d[v].append(k)
leaves = [k for k, v in d.items() if len(v) == 1]
def len_path(node, length=0, coming_from=None):
max_loc_len = length
loc_data = A[node-1]
available_nodes = {i: A[i-1] for i in d[node]}
available_nodes.pop(coming_from, None)
for i, i_data in available_nodes.items():
cumul = length + 1 if loc_data == i_data else 0
loc_len = len_path(i, cumul, node)
if loc_len > max_loc_len:
max_loc_len = loc_len
return max_loc_len
max_len = max([len_path(leaf) for leaf in leaves])
更复杂的搜索,避免两次计算相同的路径:
# ...
def len_path(node, length=0, coming_from=None, fork=False):
max_loc_len = length
loc_data = A[node-1]
available_nodes = {i: A[i-1] for i in d[node]}
available_nodes.pop(coming_from, None)
matching_nodes = [k for k, v in available_nodes.items()
if v == loc_data and k not in leaves[:explored]]
if len(matching_nodes) > 1:
fork = True
if not available_nodes and not fork and node in leaves[explored:]:
# Reached an unexplored leaf without forks on the path,
# hence no need to explore it later
leaves.remove(node)
for i, i_data in available_nodes.items():
cumul = length + 1 if loc_data == i_data else 0
loc_len = len_path(i, cumul, node, fork)
if loc_len > max_loc_len:
max_loc_len = loc_len
return max_loc_len
explored = 0
max_len =0
while explored < len(leaves):
length = len_path(leaves[explored])
if length > max_len:
max_len = length
explored += 1
答案 1 :(得分:0)
一种方法可以像这样:
最大直径将是答案
答案 2 :(得分:0)
更简单的方法:
import operator
A = [1, 1, 1 ,2, 2]
d = {}
final = {}
def func(node, val):
if len(A) < node: return 0
if A[node-1] == val: return 1
else: return 0
for idx, a in enumerate(A):
id = idx+1
d[id] = (a,func(id+id, a),func((id*2)+1 , a))
for val in d.values():
i1,i2,i3 = val
if i1 not in final:
final[i1] = 0
final[i1] += i2 + i3
print(max(final.iteritems(),key = operator.itemgetter(1))[1])