Interview Question
Software Engineer / DevelopersCountry: Russia
Interview Type: In-Person
firstly, I implemented this variant, but interviewer said that there must be only 1 function, not 2 or more functions that call one another.
And second his restriction: there should be only 1 parameter in the function: Node node.
Mhh not sure if I understand the requirement regarding the one function because the second one is private.
But if you really need only 1 method, Akhil wrote a solution which is basically comparable to my solution if you put retVal as instance variable and place the code of the private method into the public method.
The disadvantage of such a solution is that two threads accessing the getAllNodes method in parallel might change the result, no?
Try recursion method as below:
package com.returnallnodes;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Node {
Iterator<Node> children;
public static Iterator<Node> getAllNodes(Node root){
List<Node> allNodes=new ArrayList<Node>();
if(root!=null){
while(root.children.hasNext()){
Iterator<Node> childNodes=getAllNodes(root.children.next());
while(childNodes.hasNext()){
allNodes.add(childNodes.next());
}
}
}
return allNodes.iterator();
}
}
c#.
variant 1 (recursive) (DFS)
private static IEnumerable<Node> Get1( Node node ) {
var result = new HashSet<Node> { node };
if ( node.Children == null ) { return result; }
result.UnionWith( node.Children );
foreach ( var child in node.Children ) {
result.UnionWith( Get1( child ) );
}
return result;
}
c#.
variant 2 (recursive) (DFS)
private static IEnumerable<Node> Get2( Node node ) {
var result = new List<Node> { node };
if ( node.Children == null ) { return result; }
foreach ( var child in node.Children ) {
var tmpRes = result;
result = (List<Node>)new AggFunc( // AggFunc = Func<IEnumerable<Node>>;
() => { tmpRes.AddRange( Get2( child ) ); return tmpRes; } )();
}
return result;
}
c#.
variant 3 (recursive) (DFS) (using Linq extension methods)
static private IEnumerable<Node> Get3( Node node ) {
var result = new List<Node> { node };
if ( node.Children == null ) { return result; }
return node.Children.Aggregate(result, (current, child) =>
(List<Node>)new AggFunc( // AggFunc = Func<IEnumerable<Node>>;
() => { current.AddRange( Get3( child ) ); return current; } )() );
}
c#.
variant 4 (recursive) (DFS) (using Linq extension methods)
static private IEnumerable<Node> Get4( Node node ) {
var res = new List<Node> { node };
if ( node.Children == null ) { return res; }
return node.Children.Aggregate( res, (curr, child) => curr.Concat( Get4( child ) ).ToList() );
}
c#.
variant 5 (iterative) (BFS)
static private IEnumerable<Node> Get5( Node node ) {
var res = new List<Node>();
var currList = new List<Node> { node };
while ( currList.Count > 0 ) {
var tmpList = new List<Node>();
for ( int i = 0; i < currList.Count; i++ ) {
var children = currList[ i ].Children;
if ( children == null ) { continue; }
tmpList.AddRange( children );
}
res.AddRange( currList );
currList = tmpList;
}
return res;
}
I would suggest a DFS. Let me know if you find an error or a better solution
- Scavi December 04, 2015