我有一种从另一种方法输出的树形结构,格式为:
$tracks = [[1,4],[3,5],[2,3,5],[1,2],[2,4]];
顶部节点为空数组,$tracks[0] = [1,4]
合并前两个节点(1
或4
)。从$tracks[2] = [2,3,5]
看,这不是二叉树,这意味着有三个可能的节点。
我想找到数字不重复的第一个组合(例如[1,3,5,2,4]
),因此不需要遍历整棵树。
我创建了一个函数,但是遇到了一个我无法解决的问题:
$availableTracks = [[1,4],[3,5],[2,3,5],[1,2],[2,4]];
$availableTracks2 = [[1,4],[3,5],[2,3,5],[1],[2,4]];
/*
$pairedTracks = all tracks given
$currentPath = generated path
$level = which level in tree
$nodeElement = element position
$previousnode = which node it started from in current level
*/
function findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode){
if (in_array($pairedtracks[$level][$nodeElement],$currentPath)){
echo "[IN ARRAY]: Node element in current: ".$pairedtracks[$level][$nodeElement]." on level: ".$level;
echo "<br>";
echo "Node which level lowered from: ".$previousNode;
echo "<br>";
//Check if node element is in array
$maxLength = count($pairedtracks[$level]);
if ($nodeElement+1 == $maxLength){
//Current was final, return back up
$level -= 1;
// Go forward from previous
$previousNode += 1;
// Set new start node in recursive function
$nodeElement = $previousNode;
if ($nodeElement == count($pairedtracks[$level])){
//Check if node element is on the same length, then go back even more.
/*
At this point i realized that i'm going to need to keep track of too many previous iterations
*/
}
echo "Moving back up to level: ".$level.", starting iteration from: ".$nodeElement;
echo "<br>";
// Remove previously added element from that level!
array_splice($currentPath, $currentPath[count($currentPath)-1], 1);
return findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode);
}
else {
//More elements to follow
$nodeElement += 1;
return findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode);
}
}
else {
//Was not in array, element can be added to current path
echo "Adding element to current path: ".$pairedtracks[$level][$nodeElement];
echo "<br>";
$currentPath[] = $pairedtracks[$level][$nodeElement];
//Check if path has finalized or check more
if (count($currentPath) == count($pairedtracks)){
//Search finished
return $currentPath;
}
else {
//Move downwards
$level += 1;
return findBestPath($pairedtracks,$currentPath,$level,0,$nodeElement);
}
}
}
$path = findBestPath($availableTracks2,[],0,0,0);
foreach ($path as &$value) {
echo $value." ";
}
它适用于availableTracks
,但是在必须返回多个级别时会遇到问题。我得出的结论是,我需要保留多个previousnode
,但我确信应该可以不将其保留在内存中,而只需按照每次递归修改数组的长度即可。不幸的是,我想不出办法,也许有人可以帮我解决这个问题?
答案 0 :(得分:0)
不确定为什么我没有任何评论就被否决了,但是我认为我设法解决了这个问题:
$availableTracks = [[1,4],[3,5],[2,3,5],[1,2],[2,4]];
$availableTracks2 = [[1,4],[3,5],[2,3,5],[1],[2,4]];
function findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode){
$maxLength = count($pairedtracks[$level]);
if ($nodeElement == $maxLength){
echo "[Back up more]<br>";
echo "Current pair: [";
foreach ($pairedtracks[$level] as &$pairElement){
echo $pairElement.",";
}
echo "]<br>";
echo "Current path: [";
foreach ($currentPath as &$pathElement){
echo $pathElement.",";
}
echo "]<br>";
//Current was final, return back up
$level -= 1;
$lastInserted = $currentPath[count($currentPath)-1];
//Take index from previous level
$indexNumber = 0;
foreach ($pairedtracks[$level] as &$pairElement){
echo "Pair: ".$pairElement."<br>";
if ($pairElement == $lastInserted){
break;
}
$indexNumber += 1;
}
echo "Previous element was on index ".$indexNumber."<br>";
$nodeElement = $indexNumber+1;
echo "Moving back up to level: ".$level.", starting iteration from: ".$nodeElement.", removed element: ".$currentPath[count($currentPath)-1];
echo "<br>";
// Remove previously added element from that level!
array_splice($currentPath, count($currentPath)-1, 1);
return findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode);
}
else if (in_array($pairedtracks[$level][$nodeElement],$currentPath)){
echo "[IN ARRAY]: Node element in current: ".$pairedtracks[$level][$nodeElement]." on level: ".$level;
echo "<br>";
//Check if node element is in array
if ($nodeElement+1 >= $maxLength){
//Current was final, return back up
$level -= 1;
$lastInserted = $currentPath[count($currentPath)-1];
//Take index from previous level
$indexNumber = 0;
foreach ($pairedtracks[$level] as &$pairElement){
if ($pairElement == $lastInserted){
break;
}
$indexNumber += 1;
}
echo "Previous element was on index ".$indexNumber."<br>";
$nodeElement = $indexNumber+1;
echo "Moving back up to level: ".$level.", starting iteration from: ".$nodeElement.", removed element: ".$currentPath[count($currentPath)-1];
echo "<br>";
// Remove previously added element from that level!
array_splice($currentPath, count($currentPath)-1, 1);
return findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode);
}
else {
//More elements to follow
$nodeElement += 1;
return findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode);
}
}
else {
//Was not in array, element can be added to current path
echo "Adding element to current path: ".$pairedtracks[$level][$nodeElement];
echo "<br>";
$currentPath[] = $pairedtracks[$level][$nodeElement];
//Check if path has finalized or check more
if (count($currentPath) == count($pairedtracks)){
//Search finished
return $currentPath;
}
else {
//Move downwards
$level += 1;
return findBestPath($pairedtracks,$currentPath,$level,0,$nodeElement);
}
}
}
$path = findBestPath($availableTracks,[],0,0,0);
foreach ($path as &$value) {
echo $value." ";
}
我使用currentPath
作为存储工具。在返回上一级之前,我在currentPath
中使用了最后一个元素(移回顶部时将其删除),并检查它在上一级的索引是什么。然后,我从该索引开始迭代(因为以前的索引已经完成)。