Tuesday, May 15, 2012
Marker Interfaces
Marker interfaces are interfaces which do not define any functions. But by using the language capabilities (for e.g. reflection in java) you can have a certain capabilities if a class implements a marker interface.
for e.g. Suppose you have a marker interface 'MarkerInterface'
public interface MarkerInterface
{
// Nothing here
}
Now you can check if any class implements the MarkerInterface and provide a functionality by doing something like this:
if(object instanceof MarkerInterface)
{
// do something specific
}
These are a few interesting links that can tell more about Marker Interfaces:
http://en.wikipedia.org/wiki/Marker_Interface_pattern
http://geekexplains.blogspot.com/2009/10/marker-interface-in-java-what-why-uses.html
http://www.coderanch.com/t/409760/java/java/Marker-Interface
http://www.jguru.com/faq/view.jsp?EID=224126
And of course you can google to find out more..
for e.g. Suppose you have a marker interface 'MarkerInterface'
public interface MarkerInterface
{
// Nothing here
}
Now you can check if any class implements the MarkerInterface and provide a functionality by doing something like this:
if(object instanceof MarkerInterface)
{
// do something specific
}
These are a few interesting links that can tell more about Marker Interfaces:
http://en.wikipedia.org/wiki/Marker_Interface_pattern
http://geekexplains.blogspot.com/2009/10/marker-interface-in-java-what-why-uses.html
http://www.coderanch.com/t/409760/java/java/Marker-Interface
http://www.jguru.com/faq/view.jsp?EID=224126
And of course you can google to find out more..
Construct binary tree given its inorder and preorder traversal
Construction of Binary tree given its inorder and preorder traversal.
public static Node construct(String preorder, String inorder, int start, int end, int [] preorderIndex)
{
if(start > end)
return null;
Node root = new Node(preorder.charAt(preorderIndex[0]));
++preorderIndex[0];
int inorderIndex = inorder.indexOf(""+root.data);
root.left = construct(preorder, inorder, start, inorderIndex - 1, preorderIndex);
root.right = construct(preorder, inorder, inorderIndex + 1, end, preorderIndex);
return root;
}
public static void main(String[] args) {
String preorder = "ABCDEFG";
String inorder = "GFEDCBA";
// We use this as a reference object, so that we pick the correct value from preorder array during
// recursion. This could be done by having a static variable as well.
int [] preorderIndex = new int[1];
Node root = CodeSamples.construct(preorder, inorder, 0, preorder.length() - 1, preorderIndex);
// Verify if it build correctly
BinaryTree.preorderTraversal(root);
System.out.println();
BinaryTree.inorderTraversal(root);
}
For explanation of the approach and other ways of doing it, visit this link: http://www.geeksforgeeks.org/archives/6633
Thursday, May 10, 2012
Adding two linked lists
Given 2 singly linked lists which have single digit data, add the two lists and return a new list.
For e.g.
list1: 4->5->5->9->8
list2: 2->3->1->1
Output should be: 4->7->9->0->9
Approach 1: One of the approach can be to reverse both the linked list and then add node by node. In that case you will need to reverse the output list as well.
Approach 2: The other approach is to put the linked lists in the stack. This avoids the need to reverse the lists.
public static Node addLinkedLists(Node head1, Node head2)
{
if(head1 == null)
return head2 != null ? head2 : null;
if(head2 == null)
return head1 != null ? head1 : null;
Stack<node> s1 = new Stack<node>();
Stack<node> s2 = new Stack<node>();
Stack<node> s3 = new Stack<node>();
Node list1 = head1;
Node list2 = head2;
while(list1 != null)
{
s1.push(list1);
list1 = list1.next;
}
while(list2 != null)
{
s2.push(list2);
list2 = list2.next;
}
int carry = 0;
while(!s1.empty() && !s2.empty())
{
int total = carry + s1.pop().data + s2.pop().data;
Node n = new Node(total%10);
s3.push(n);
carry = total/10;
}
while(!s1.empty())
{
int total = carry + s1.pop().data;
Node n = new Node(total%10);
s3.push(n);
carry = total/10;
}
while(!s2.empty())
{
int total = carry + s2.pop().data;
Node n = new Node(total%10);
s3.push(n);
carry = total/10;
}
Node result = s3.pop();
Node retHead = result;
while(!s3.empty())
{
Node n = s3.pop();
result.next = n;
result = n;
}
return retHead;
}
Both approaches have similar run time complexity but the stack based approach requires more space.
Initialization-on-demand holder idiom
Almost everyone knows how the singleton pattern works. It looks something as follows:
This code would won't correctly in case of an multi-threaded environment. For it to work in a multi-threaded environment you will add some synchronization code.
However I came across this new way to assure singleton instance in Java. It is called Initialization-on-demand holder idiom. You can read about it here: http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
It relies on the defined initialization phase of execution within the JVM.
class Singleton
{
private static Singleton _instance;
private Singleton(){ }
public Singleton getInstance()
{
if(_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
This code would won't correctly in case of an multi-threaded environment. For it to work in a multi-threaded environment you will add some synchronization code.
However I came across this new way to assure singleton instance in Java. It is called Initialization-on-demand holder idiom. You can read about it here: http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
It relies on the defined initialization phase of execution within the JVM.
Wednesday, April 18, 2012
Deep Copy of a doubly linked list where previous pointers point to any arbitrary node in the list
Given a doubly linked list which looks as follows, make a deep copy of the linked list and return the head of the new linked list.
Deep copy implies that we have to make an exact copy of each node in the original list and assign the pointers same as that of the original list.
Since the previous pointers point to any arbitrary node in the list, we need to keep an association between nodes of the old linked list and the new liked list.
Here are 2 ways I can think of doing this. Both of them are O(n) in time but method 1 takes O(n) space.
Method 1:
In this method we save the association in the form of an hashtable.
public static Node deepCopy(Node head)
{
if(head == null)
return null;
Node oldHead = head;
// Traverse the original doubly linked list and create a new
// singly linked list
// When creating the new linked list save the association between
// corresponding old and new nodes in a hashtable
// For e.g. original: 1->2->3->4
// new: 1'->2'->3'->4'
// hashtable contains mapping of [1->1'], [2->2'],..
Hashtable<node, node> oldToNewNodeMap = new Hashtable<node, node>();
// Create the new head
Node newHead = new Node(oldHead.data+"'");
oldToNewNodeMap.put(oldHead, newHead);
Node tmp = newHead;
oldHead = oldHead.next;
// Create rest of the singly linked list with next pointers
while(oldHead != null)
{
Node newNode = new Node(oldHead.data+"'");
oldToNewNodeMap.put(oldHead, newNode);
tmp.next = newNode;
oldHead = oldHead.next;
tmp = tmp.next;
}
tmp = newHead;
oldHead = head;
// Now assign the prev pointers
while(oldHead != null)
{
tmp.prev = oldToNewNodeMap.get(oldHead.prev);
oldHead = oldHead.next;
tmp = tmp.next;
}
return newHead;
}
Method 2:
In this method we modify the original linked list for the time being to store the association and then revert it back to the original linked list.
public static Node deepCopy(Node head)
{
if(head == null)
return null;
// Rather than using a hastable create new association in
// the following way:
// Create new nodes and insert it into the original linked list
// as follows
// For e.g. 1->1'->2->2'->3->3'->4->4' where 1', 2',.. are
// the new nodes created
Node curNode = head;
while(curNode != null)
{
Node newNode = new Node(curNode.data+"'");
// New node's next points to current node's next
// New node's previous continues to point to current node's prev
newNode.next = curNode.next;
newNode.prev = curNode.prev;
// Current node should now point to the new node
Node next = curNode.next;
curNode.next = newNode;
// Advance to the original list's node
curNode = next;
}
// Now assign correct previous pointer for alternate node (alternate
// nodes are the new nodes but they currently point to the prev
// of original nodes)
curNode = head;
boolean odd = true;
while(curNode != null)
{
if(!odd)
{
curNode.prev = curNode.prev.next;
}
odd = !odd;
curNode = curNode.next;
}
// Now break the linked list into original and new linked list
curNode = head;
Node newHead = curNode.next;
while(curNode != null && curNode.next != null)
{
Node p = curNode;
Node n = curNode.next.next;
curNode = curNode.next;
p.next = n;
}
return newHead;
}
As you can see method 1 traverses the list thrice but requires less space whereas method 1 traverses the list twice but requires extra space.
Labels:
algorithms,
doubly linked list,
linked list,
problem solving
Tuesday, April 17, 2012
Swap nodes of a linked list
For e.g:
Input: 1->2->3->4->5->6
Output: 2->1->4->3->6->5
There are 2 ways I could think by which we can solve this. Both methods take O(n) time.
Method 2 however is more elegant.
Method 1:
Method 2:
Input: 1->2->3->4->5->6
Output: 2->1->4->3->6->5
There are 2 ways I could think by which we can solve this. Both methods take O(n) time.
Method 2 however is more elegant.
Method 1:
public static Node swapNodes(Node head)
{
Node c = head;
Node p = c;
boolean headSet = false;
while(c != null && c.next != null)
{
Node n = c.next;
c.next = n.next;
n.next = c;
if(!headSet)
{
head = n;
headSet = true;
}
else
{
p.next = n;
p = c;
}
c = c.next;
}
return head;
}
Method 2:
public static Node swapNodes(Node head)
{
Node c = head;
// Create a dummy node before the head node
Node dummy = new Node();
dummy.next = head;
Node p = dummy;
while(c != null && c.next != null)
{
Node n = c.next;
c.next = n.next;
n.next = c;
p.next = n;
p = c;
c = c.next;
}
return dummy.next;
}
Subscribe to:
Posts (Atom)
