I know if we deal with graph DFS, we use stack to track the node visited. But the code below is also using DFS. I read it a few times but still cannot figure out where it is DFS.Thanks!
public ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> item = new ArrayList<Integer>();
if(candidates == null || candidates.length==0)
return res;
Arrays.sort(candidates);
helper(candidates,target, 0, item ,res);
return res;
}
private void helper(int[] candidates, int target, int start, ArrayList<Integer> item,
ArrayList<ArrayList<Integer>> res){
if(target<0)
return;
if(target==0){
res.add(new ArrayList<Integer>(item));
return;
}
for(int i=start;i<candidates.length;i++){
if(i>0 && candidates[i] == candidates[i-1])
item.add(candidates[i]);
int newtarget = target - candidates[i];
helper(candidates,newtarget,i,item,res);
item.remove(item.size()-1);
}
}
The DFS can be implemented using 2 basic techniques:
1. Using Stack
2. Using Recursion.
I know that you find it hard to believe that the code you provided is using DFS because you don't see an explicit stack anywhere. The Reason is because it has implemented DFS using the second technique.
And the second technique is very easy to implement too. The psuedocode for it is very simple.
DFS( vertex v )
{
mark v visited
for all unvisited vertices u adjacent to v
{
DFS(u)
}
}
The code you provided is using this simple technique only, but if you have studied the course Operating System, you will come to know that recursion uses the program stack to keep track of function calls, so you are indirectly still using stack, but that is a different issue.
Related
I have read an article from here about how to detect cycle in a directed graph. The basic concept of this algorithm is if a node is found in recursive stack then there is a cycle, but i don't understand why. what is the logic here?
#include<iostream>
#include <list>
#include <limits.h>
using namespace std;
class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
bool isCyclicUtil(int v, bool visited[], bool *rs);
public:
Graph(int V); // Constructor
void addEdge(int v, int w); // to add an edge to graph
bool isCyclic(); // returns true if there is a cycle in this graph
};
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v’s list.
}
bool Graph::isCyclicUtil(int v, bool visited[], bool *recStack)
{
if(visited[v] == false)
{
// Mark the current node as visited and part of recursion stack
visited[v] = true;
recStack[v] = true;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i)
{
if ( !visited[*i] && isCyclicUtil(*i, visited, recStack) )
return true;
else if (recStack[*i])
return true;
}
}
recStack[v] = false; // remove the vertex from recursion stack
return false;
}
bool Graph::isCyclic()
{
// Mark all the vertices as not visited and not part of recursion
// stack
bool *visited = new bool[V];
bool *recStack = new bool[V];
for(int i = 0; i < V; i++)
{
visited[i] = false;
recStack[i] = false;
}
for(int i = 0; i < V; i++)
if (isCyclicUtil(i, visited, recStack))
return true;
return false;
}
int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
if(g.isCyclic())
cout << "Graph contains cycle";
else
cout << "Graph doesn't contain cycle";
return 0;
}
From a brief look, the code snippet is an implementation of depth-first search, which is a basic search technique for directed graphs; the same approach works for breadth-first search. Note that apparently this implementation works only if there is only one connected component, otherwise the test must be performed for each connected component until a cycle is found.
That being said, the technique works by choosing one node at will and starting a recursive search there. Basically, if the search discovers a node that is in the stack, there must be a cycle, since it has been previously reached.
In the current implementation, recStack is not actually the stack, it just indicates whether a specific node is currently in the stack, no sequence information is stored. The actual cycle is contained implicitly in the call stack. The cycle is the sequence of nodes for which the calls of isCyclicUtil has not yet returned. If the actual cycle has to be extracted, the implementation must be changed.
So essentailly, what this is saying, is if a node leads to itself, there is a cycle. This makes sense if you think about it!
Say we start at node1.
{node1 -> node2}
{node2 -> node3}
{node3 -> node4
node3 -> node1}
{node4 -> end}
{node1 -> node2}
{node2 -> node3}.....
This is a small graph that contains a cycle. As you can see, we traverse the graph, going from each node to the next. In some cases we reach and end, but even if we reach the end, our code wants to go back to the other branch off of node3 so that it can check it's next node. This node then leads back to node1.
This will happen forever if we let it, because the path starting at node1 leads back to itself. We are recursively putting each node we visit on the stack, and if we reach an end, we remove all of the nodes from the stack AFTER the branch. In our case, we would be removing node4 from the stack every time we hit the end, but the rest of the nodes would stay on the stack because of the branch off of node3.
Hope this helps!
Alright so i was implementing a solution of a problem which started of by giving you a (n,n) grid. It required me to to start at (1,1), visit certain points in the grid, marked as * and then finally proceed to (n,n). The size of the grid is guaranteed to be not more then 15 and the number of points to visit , * is guaranteed to be >=0 and <=n-2. The start and end points are always empty. There are certain obstacles , # where I cannot step on. Also, if i have visited a point before reaching a certain *, i can go through it again after collecting *.
Here is what my solution does. I made a datastructure called 'Node' which has 2 integer datatypes (x,y). It's basically a tuple.
class Node
{
int x,y;
Node(int x1,int y1)
{
x=x1;
y=y1;
}
}
While taking in the grid, i maintain a Set which stores the coordinates of '*' in the grid.
Set<Node> points=new HashSet<Node>();
I maintain a grid array and also a distance array
char [][]
int distances [][]
Now what i do is, i apply BFS as (1,1) as source. As soon as i encounter any '*' ( Which i believe will be the closest because BFS provides us with the shortest path in an unweighted graph ), I remove it from the Set.
Now i apply BFS again where my source becomes the last coordinate of '*' found. Everytime, i refresh the distance array since my source coordinate has changed. For the grid array, i refresh the paths marked as 'V' (visited) for the previous iteration.
This entire process continues until i reach the last '*'.
BTW if my BFS returns -1, the program prints '-1' and quits.
Now if I have successfully reached all '' in the shortest possible way(i guess?), i set the (n,n) coordinate in the Grid as '' and apply BFS one last time. This way i get to the final point.
Now my solution seemd to be failing somewhere. Have gone wrong somewhere? Is my concept wrong? Does this 'greedy' approach fail? Getting the shortest path between all '*' checkpoints should eventually get me the shortest path IMO.
I looked around and saw this this problem is similar to the Travelling Salesman problem and also solvable by Dynamic Programming and DFS mix or A* algorithm.I have no clue how though. Someone even said dijkstra between each * but according to my knowledge, in an unweighted graph, Dijktra and BFS work the same. I just want to know why this BFS solution fails
Finally, Here is my code:
import java.io.*;
import java.util.*;
/**
* Created by Shreyans on 5/2/2015 at 2:29 PM using IntelliJ IDEA (Fast IO Template)
*/
//ADD PUBLIC FOR CF,TC
class Node
{
int x,y;
Node(int x1,int y1)
{
x=x1;
y=y1;
}
}
class N1
{
//Datastructures and Datatypes used
static char grid[][];
static int distances[][];
static int r=0,c=0,s1=0,s2=0,f1=0,f2=0;
static int dx[]={1,-1,0,0};
static int dy[]={0,0,-1,1};
static Set<Node> points=new HashSet<Node>();
static int flag=1;
public static void main(String[] args) throws IOException
{
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();//testcases
for(int ixx=0;ixx<t;ixx++)
{
flag=1;
r=sc.nextInt();
if(r==1)
{
sc.next();//Taking in '.' basically
System.out.println("0");//Already there
continue;
}
c=r;//Rows guarenteed to be same as rows. It a nxn grid
grid=new char[r][c];
distances=new int[r][c];
points.clear();
for(int i=0;i<r;i++)
{
char[]x1=sc.next().toCharArray();
for(int j=0;j<c;j++)
{
grid[i][j]=x1[j];
if(x1[j]=='*')
{
points.add(new Node(i,j));
}
}
}//built grid
s1=s2=0;
distances[s1][s2]=0;//for 0,0
int ansd=0;
while(!points.isEmpty())
{
for(int i=0;i<r;i++)
{
for (int j = 0; j < c; j++)
{
distances[i][j]=0;
if(grid[i][j]=='V')//Visited
{
grid[i][j]='.';
}
}
}
distances[s1][s2]=0;
int dis=BFS();
if(dis!=-1)
{
ansd += dis;//Adding on (minimum?) distaces
//System.out.println("CURR DIS: "+ansd);
}
else
{
System.out.println("-1");
flag = 0;
break;
}
}
if(flag==1)
{
for(int i11=0;i11<r;i11++)
{
for(int j1=0;j1<c;j1++)
{
if(grid[i11][j1]=='V')//These pnts become accesible in the next iteration again
{
grid[i11][j1]='.';
}
distances[i11][j1]=0;
}
}
f1=r-1;f2=c-1;
grid[f1][f2]='*';
int x=BFS();
if(x!=-1)
{
System.out.println((ansd+x));//Final distance
}
else
{
System.out.println("-1");//Not possible
}
}
}
}
public static int BFS()
{
// Printing current grid correctly according to concept
System.out.println("SOURCE IS:"+(s1+1)+","+(s2+1));
for(int i2=0;i2<r;i2++)
{
for (int j1 = 0; j1 < c; j1++)
{
{
System.out.print(grid[i2][j1]);
}
}
System.out.println();
}
Queue<Node>q=new LinkedList<Node>();
q.add(new Node(s1,s2));
while(!q.isEmpty())
{
Node p=q.poll();
for(int i=0;i<4;i++)
{
if(((p.x+dx[i]>=0)&&(p.x+dx[i]<r))&&((p.y+dy[i]>=0)&&(p.y+dy[i]<c))&&(grid[p.x+dx[i]][p.y+dy[i]]!='#'))
{//If point is in range
int cx,cy;
cx=p.x+dx[i];
cy=p.y+dy[i];
distances[cx][cy]=distances[p.x][p.y]+1;//Distances
if(grid[cx][cy]=='*')//destination
{
for(Node rm:points)// finding the node and removing it
{
if(rm.x==cx&&rm.y==cy)
{
points.remove(rm);
break;
}
}
grid[cx][cy]='.';//It i walkable again
s1=cx;s2=cy;//next source set
return distances[cx][cy];
}
else if(grid[cx][cy]=='.')//Normal tile. Now setting to visited
{
grid[cx][cy]='V';//Adding to visited
q.add(new Node(cx,cy));
}
}
}
}
return -1;
}
}
Here is my code in action for a few testcases. Gives the correct answer:
JAVA: http://ideone.com/qoE859
C++ : http://ideone.com/gsCSSL
Here is where my code fails: http://www.codechef.com/status/N1,bholagabbar
Your idea is wrong. I haven't read the code because what you describe will fail even if implemented perfectly.
Consider something like this:
x....
.....
..***
....*
*...*
You will traverse the maze like this:
x....
.....
..123
....4
*...5
Then go from 5 to the bottom-left * and back to 5, taking 16 steps. This however:
x....
.....
..234
....5
1...6
Takes 12 steps.
The correct solution to the problem involves brute force. Generate all permutations of the * positions, visit them in the order given by the permutation and take the minimum.
13! is rather large though, so this might not be fast enough. There is a faster solution by dynamic programming in O(2^k), similar to the Travelling Salesman Dynamic Programming Solution (also here).
I don't have time to talk about the solution much right now. If you have questions about it, feel free to ask another question and I'm sure someone will chime in (or leave this one open).
I have seen quite a lot of algorithms to do cycle detection, such as Tarjan's strongly connected components algorithm answered in Best algorithm for detecting cycles in a directed graph.
I never thought detecting a cycle would be that complicated and I always believed a simple Set can help solve the problem.
So in addition to the usual marker array for recording visited vertices, we can use an additional Set to record all vertices along a path from the source.
The key thing is to remember to remove a vertex from the set after all its next neighbours are done.
A trivial code is like this:
public boolean hasCycle(List<Integer>[] vs) {
boolean[] marker = new boolean[v.length];
Set<Integer> tracker = new HashSet<Integer>();
for(int v = 0;v < vs.length;v++)
if (explore(v, vs, marker, tracker)) return true;
return false;
}
private boolean explore(int v, List<Integer>[] vs, boolean[] marker, Set<Integer> tracker) {
if (tracker.contains(v)) return true;
else if (!marker[v]) {
marker[v] = true;
tracker.add(v); // add current vertex to tracker
for (int u:vs[v]) if (explore(v, vs, marker, tracker)) return true;
tracker.remove(v); // remove the vertex from tracker, as it is fully done.
}
else return false;
}
Is there any problem about this algorithm?
With help from sasha's answer, actually even the set is not necessary and just an array is enough.
public boolean hasCycle(List<Integer>[] vs) {
boolean[] marker = new boolean[v.length];
boolean[] onPath = new boolean[v.length];
for(int v = 0;v < vs.length;v++)
if (explore(v, vs, marker, onPath)) return true;
return false;
}
private boolean explore(int v, List<Integer>[] vs, boolean[] marker, boolean[] onPath) {
if (onPath[v]) return true;
else if (!marker[v]) {
marker[v] = true;
onPath[v] = true; // add current vertex to the path
for (int u:vs[v]) if (explore(v, vs, marker, onPath)) return true;
onPath[v] = false; // remove the vertex from the path, as it is fully done.
}
else return false;
}
I am not an expert in java but talking about C++ passing set etc in recursion is not time efficient. Also set takes O(log(n)) in inserting/deleting an element. Your logic looks correct to me. But you can do it more efficiently and easily by keeping two arrays parent[] and visited[]. Basically do a bfs and following is the pseudo code ( visited is initialized to all zeros ) .
/* There are n nodes from 0 to n-1 */
visited[0]=1
parent[0]=0
flag=0
queue.push(0)
while the queue is not empty
top = queue.front()
queue.pop()
for all neighbors x of top
if not visited[top]
visited[x]=1
parent[x]=top
queue.push(x)
else if visited[x] is 1 and parent[top] is not x
flag = 1
if flag is 1 cycle is there otherwise not
As it may not be necessary that starting from 0 all nodes are visited . So repeat until all nodes are visited. Complexity is O(E+V) slightly better than the complexity of your method O(E+VlogV). But it is simple to write and not recursive.
Three types of tree traversals are inorder, preorder, and post order.
A fourth, less often used, traversal is level-order traversal. In a
level-order traveresal, all nodes at depth "d" are processed before
any node at depth d + 1. Level-order traversal differs from the other
traversals in that it is not done recursively; a queue is used,
instead of the implied stack of recursion.
My questions on above text snippet are
Why level order traversals are not done recursively?
How queue is used in level order traversal? Request clarification with Pseudo code will be helpful.
Thanks!
Level order traversal is actually a BFS, which is not recursive by nature. It uses Queue instead of Stack to hold the next vertices that should be opened. The reason for it is in this traversal, you want to open the nodes in a FIFO order, instead of a LIFO order, obtained by recursion
as I mentioned, the level order is actually a BFS, and its [BFS] pseudo code [taken from wikipedia] is:
1 procedure BFS(Graph,source):
2 create a queue Q
3 enqueue source onto Q
4 mark source
5 while Q is not empty:
6 dequeue an item from Q into v
7 for each edge e incident on v in Graph:
8 let w be the other end of e
9 if w is not marked:
10 mark w
11 enqueue w onto Q
(*) in a tree, marking the vertices is not needed, since you cannot get to the same node in 2 different paths.
void levelorder(Node *n)
{ queue < Node * >q;
q.push(n);
while(!q.empty())
{
Node *node = q.front();
cout<<node->value;
q.pop();
if(node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
}
}
Instead of a queue, I used a map to solve this. Take a look, if you are interested. As I do a postorder traversal, I maintain the depth at which each node is positioned and use this depth as the key in a map to collect values in the same level
class Solution {
public:
map<int, vector<int> > levelValues;
void recursivePrint(TreeNode *root, int depth){
if(root == NULL)
return;
if(levelValues.count(root->val) == 0)
levelValues.insert(make_pair(depth, vector<int>()));
levelValues[depth].push_back(root->val);
recursivePrint(root->left, depth+1);
recursivePrint(root->right, depth+1);
}
vector<vector<int> > levelOrder(TreeNode *root) {
recursivePrint(root, 1);
vector<vector<int> > result;
for(map<int,vector<int> >::iterator it = levelValues.begin(); it!= levelValues.end(); ++it){
result.push_back(it->second);
}
return result;
}
};
The entire solution can be found here - http://ideone.com/zFMGKU
The solution returns a vector of vectors with each inner vector containing the elements in the tree in the correct order.
you can try solving it here - https://oj.leetcode.com/problems/binary-tree-level-order-traversal/
And, as you can see, we can also do this recursively in the same time and space complexity as the queue solution!
My questions on above text snippet are
Why level order traversals are not done recursively?
How queue is used in level order traversal? Request clarification with Pseudo code will be helpful.
I think it'd actually be easier to start with the second question. Once you understand the answer to the second question, you'll be better prepared to understand the answer to the first.
How level order traversal works
I think the best way to understand how level order traversal works is to go through the execution step by step, so let's do that.
We have a tree.
We want to traverse it level by level.
So, the order that we'd visit the nodes would be A B C D E F G.
To do this, we use a queue. Remember, queues are first in, first out (FIFO). I like to imagine that the nodes are waiting in line to be processed by an attendant.
Let's start by putting the first node A into the queue.
Ok. Buckle up. The setup is over. We're about to start diving in.
The first step is to take A out of the queue so it can be processed. But wait! Before we do so, let's put A's children, B and C, into the queue also.
Note: A isn't actually in the queue anymore at this point. I grayed it out to try to communicate this. If I removed it completely from the diagram, it'd make it harder to visualize what's happening later on in the story.
Note: A is being processed by the attendant at the desk in the diagram. In real life, processing a node can mean a lot of things. Using it to compute a sum, send an SMS, log to the console, etc, etc. Going off the metaphor in my diagram, you can tell the attendant how you want them to process the node.
Now we move on to the node that is next in line. In this case, B.
We do the same thing that we did with A: 1) add the children to the line, and 2) process the node.
Hey, check it out! It looks like what we're doing here is going to get us that level order traversal that we were looking for! Let's prove this to ourselves by continuing the step through.
Once we finish with B, C is next in line. We place C's children at the back of the line, and then process C.
Now let's see what happens next. D is next in line. D doesn't have any children, so we don't place anything at the back of the line. We just process D.
And then it's the same thing for E, F, and G.
Why it's not done recursively
Imagine what would happen if we used a stack instead of a queue. Let's rewind to the point where we had just visited A.
Here's how it'd look if we were using a stack.
Now, instead of going "in order", this new attendant likes to serve the most recent clients first, not the ones who have been waiting the longest. So C is who is up next, not B.
Here's where the key point is. Where the stack starts to cause a different processing order than we had with the queue.
Like before, we add C's children and then process C. We're just adding them to a stack instead of a queue this time.
Now, what's next? This new attendant likes to serve the most recent clients first (ie. we're using a stack), so G is up next.
I'll stop the execution here. The point is that something as simple as replacing the queue with a stack actually gives us a totally different execution order. I'd encourage you to finish the step through though.
You might be thinking: "Ok... but the question asked about recursion. What does this have to do with recursion?" Well, when you use recursion, something sneaky is going on. You never did anything with a stack data structure like s = new Stack(). However, the runtime uses the call stack. This ends up being conceptually similar to what I did above, and thus doesn't give us that A B C D E F G ordering we were looking for from level order traversal.
https://github.com/arun2pratap/data-structure/blob/master/src/main/java/com/ds/tree/binarytree/BinaryTree.java
for complete can look out for the above link.
public void levelOrderTreeTraversal(List<Node<T>> nodes){
if(nodes == null || nodes.isEmpty()){
return;
}
List<Node<T>> levelNodes = new ArrayList<>();
nodes.stream().forEach(node -> {
if(node != null) {
System.out.print(" " + node.value);
levelNodes.add(node.left);
levelNodes.add(node.right);
}
});
System.out.println("");
levelOrderTreeTraversal(levelNodes);
}
Also can check out
http://www.geeksforgeeks.org/
here you will find Almost all Data Structure related answers.
Level order traversal implemented by queue
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
def levelOrder(root: TreeNode) -> List[List[int]]:
res = [] # store the node value
queue = [root]
while queue:
node = queue.pop()
# visit the node
res.append(node.val)
if node.left:
queue.insert(0, node.left)
if node.right:
queue.insert(0, node.right)
return res
Recursive implementation is also possible. However, it needs to know the max depth of the root in advance.
def levelOrder(root: TreeNode) -> List[int]:
res = []
max_depth = maxDepth(root)
for i in range(max_depth):
# level start from 0 to max_depth-1
visitLevel(root, i, action)
return res
def visitLevel(root:TreeNode, level:int, res: List):
if not root:
return
if level==0:
res.append(node.val)
else:
self.visitLevel(root.left, level-1, res)
self.visitLevel(root.right, level-1, res)
def maxDepth(root: TreeNode) -> int:
if not root:
return 0
if not root.left and not root.right:
return 1
return max([ maxDepth(root.left), maxDepth(root.right)]) + 1
For your point 1) we can use Java below code for level order traversal in recursive order, we have not used any library function for tree, all are user defined tree and tree specific functions -
class Node
{
int data;
Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
boolean isLeaf() { return left == null ? right == null : false; }
}
public class BinaryTree {
Node root;
Queue<Node> nodeQueue = new ConcurrentLinkedDeque<>();
public BinaryTree() {
root = null;
}
public static void main(String args[]) {
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.root.right.left = new Node(6);
tree.root.right.right = new Node(7);
tree.root.right.left.left = new Node(8);
tree.root.right.left.right = new Node(9);
tree.printLevelOrder();
}
/*Level order traversal*/
void printLevelOrder() {
int h = height(root);
int i;
for (i = 1; i <= h; i++)
printGivenLevel(root, i);
System.out.println("\n");
}
void printGivenLevel(Node root, int level) {
if (root == null)
return;
if (level == 1)
System.out.print(root.data + " ");
else if (level > 1) {
printGivenLevel(root.left, level - 1);
printGivenLevel(root.right, level - 1);
}
}
/*Height of Binary tree*/
int height(Node root) {
if (root == null)
return 0;
else {
int lHeight = height(root.left);
int rHeight = height(root.right);
if (lHeight > rHeight)
return (lHeight + 1);
else return (rHeight + 1);
}
}
}
For your point 2) If you want to use non recursive function then you can use queue as below function-
public void levelOrder_traversal_nrec(Node node){
System.out.println("Level order traversal !!! ");
if(node == null){
System.out.println("Tree is empty");
return;
}
nodeQueue.add(node);
while (!nodeQueue.isEmpty()){
node = nodeQueue.remove();
System.out.printf("%s ",node.data);
if(node.left !=null)
nodeQueue.add(node.left);
if (node.right !=null)
nodeQueue.add(node.right);
}
System.out.println("\n");
}
Recursive Solution in C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levels;
void helper(TreeNode* node,int level)
{
if(levels.size() == level) levels.push_back({});
levels[level].push_back(node->val);
if(node->left)
helper(node->left,level+1);
if(node->right)
helper(node->right,level+1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root) return levels;
helper(root,0);
return levels;
}
};
We can use queue to solve this problem in less time complexity. Here is the solution of level order traversal suing Java.
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> levelOrderTraversal = new ArrayList<List<Integer>>();
List<Integer> currentLevel = new ArrayList<Integer>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if(root != null)
{
queue.add(root);
queue.add(null);
}
while(!queue.isEmpty())
{
TreeNode queueRoot = queue.poll();
if(queueRoot != null)
{
currentLevel.add(queueRoot.val);
if(queueRoot.left != null)
{
queue.add(queueRoot.left);
}
if(queueRoot.right != null)
{
queue.add(queueRoot.right);
}
}
else
{
levelOrderTraversal.add(currentLevel);
if(!queue.isEmpty())
{
currentLevel = new ArrayList<Integer>();
queue.add(null);
}
}
}
return levelOrderTraversal;
}
}
I need to write a program that check if a graph is bipartite.
I have read through wikipedia articles about graph coloring and bipartite graph. These two article suggest methods to test bipartiteness like BFS search, but I cannot write a program implementing these methods.
Why can't you? Your question makes it hard for someone to even write the program for you since you don't even mention a specific language...
The idea is to start by placing a random node into a FIFO queue (also here). Color it blue. Then repeat this while there are nodes still left in the queue: dequeue an element. Color its neighbors with a different color than the extracted element and insert (enqueue) each neighbour into the FIFO queue. For example, if you dequeue (extract) an element (node) colored red, color its neighbours blue. If you extract a blue node, color its neighbours red. If there are no coloring conflicts, the graph is bipartite. If you end up coloring a node with two different colors, than it's not bipartite.
Like #Moron said, what I described will only work for connected graphs. However, you can apply the same algorithm on each connected component to make it work for any graph.
http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/breadthSearch.htm
Please read this web page, using breadth first search to check when you find a node has been visited, check the current cycle is odd or even.
A graph is bipartite if and only if it does not contain an odd cycle.
The detailed implementation is as follows (C++ version):
struct NODE
{
int color;
vector<int> neigh_list;
};
bool checkAllNodesVisited(NODE *graph, int numNodes, int & index);
bool checkBigraph(NODE * graph, int numNodes)
{
int start = 0;
do
{
queue<int> Myqueue;
Myqueue.push(start);
graph[start].color = 0;
while(!Myqueue.empty())
{
int gid = Myqueue.front();
for(int i=0; i<graph[gid].neigh_list.size(); i++)
{
int neighid = graph[gid].neigh_list[i];
if(graph[neighid].color == -1)
{
graph[neighid].color = (graph[gid].color+1)%2; // assign to another group
Myqueue.push(neighid);
}
else
{
if(graph[neighid].color == graph[gid].color) // touble pair in the same group
return false;
}
}
Myqueue.pop();
}
} while (!checkAllNodesVisited(graph, numNodes, start)); // make sure all nodes visited
// to be able to handle several separated graphs, IMPORTANT!!!
return true;
}
bool checkAllNodesVisited(NODE *graph, int numNodes, int & index)
{
for (int i=0; i<numNodes; i++)
{
if (graph[i].color == -1)
{
index = i;
return false;
}
}
return true;
}