If you're allowed to update Nodes
before purging them a simple approach would be to iterate through the array and use a recursive function to follow the path from each node to the root or a parent whose data matches the query data. In the latter case we update the data of all nodes on the path to the query value. Then, in a 2nd pass through the array we compress it, removing nodes whose value matches the query.
Here's some Java code to illustrate:
static int clearPath(Node[] arr, int query)
{
for(int i=0; i<arr.length; i++)
if(arr[i].data != query)
markPath(arr[i], query);
int j = 0;
for(int i=0; i<arr.length; i++)
if(arr[i].data != query)
arr[j++] = arr[i];
return j;
}
static boolean markPath(Node node, int query)
{
if(node == null) return false;
if(node.data == query) return true;
boolean located = markPath(node.parent, query);
if(located) node.data = query;
return located;
}
And the Node
class:
static class Node
{
Node parent;
int data;
public Node(Node parent, int data)
{
this.parent = parent;
this.data = data;
}
public String toString()
{
return String.format("(%d : %s) ", data, (parent == null ? "*" : parent.data));
}
}
Test:
int[][] tree = {{1, 2, 3, 4}, {2, 3, 4, 5}, {5, 6, 7}};
List<Node> nodeList = new ArrayList<>();
for(int[] sub : tree)
{
Node node = null;
for(int data : sub)
nodeList.add(node = new Node(node, data));
}
Node[] arr = nodeList.toArray(new Node[nodeList.size()]);
System.out.println(Arrays.toString(arr));
int n = clearPath(arr, 3);
System.out.println(Arrays.toString(Arrays.copyOfRange(arr, 0, n)));
Output:
[(1 : *) , (2 : 1) , (3 : 2) , (4 : 3) , (2 : *) , (3 : 2) , (4 : 3) , (5 : 4) , (5 : *) , (6 : 5) , (7 : 6) ]
[(1 : *) , (2 : 1) , (2 : *) , (5 : *) , (6 : 5) , (7 : 6) ]
If you're not allowed to update node data you could use a Set
to hold nodes to be removed.
static int clearPath2(Node[] arr, int query)
{
Set<Node> rem = new HashSet<>();
for(int i=0; i<arr.length; i++)
markPath2(rem, arr[i], query);
int j = 0;
for(int i=0; i<arr.length; i++)
if(!rem.contains(arr[i])) arr[j++] = arr[i];
return j;
}
static boolean markPath2(Set<Node> rem, Node node, int query)
{
if(node == null) return false;
if(node.data == query || markPath2(rem, node.parent, query))
{
rem.add(node);
return true;
}
return false;
}