Sunday, 29 December 2013

How to reverse a LinkedList in Java?

A very basic interview question asked. In an earlier post we had see the LinkedList class in java and how to reverse it using Collections.revere(). You can refer to that post. Point to note that the LinkedList class defined in java is infact a doubly Linked list and that is not what the interviewer will be interested in.  Yes you can give that as your 1st answer as it will depict you have java knowledge but at some point you will have to fall back to basics.

Before we write the code to actually reverse the LinkedList lets write the code for the LLNode  data structure which will form our LinkedList.

LinkedList Node 

public class LLNode {

    int value;
    LLNode nextNode;

    public  LLNode(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public LLNode getNextNode() {
        return nextNode;
    }

    public void setNextNode(LLNode nextNode) {
        this.nextNode = nextNode;
    }

    public static void printLL(LLNode head){
        if (head != null){
            System.out.println(head.getValue());
            printLL(head.getNextNode());
        }
    }
}

Note : In this data structure we have also provided a method printLL() to print the Linked List.

Now lets go ahead and write our code to reverse this Linked List

Linked List Reversal

public class LLReverser {

    public static LLNode reverse(LLNode root){

        if(root.getNextNode() == null){
            return root;
        }

        LLNode next = root.getNextNode();
        root.setNextNode(null);

        while(next != null){
            LLNode temp = null;
            if(next.getNextNode() != null)
                temp = next.getNextNode();
            next.setNextNode(root);
            root = next;
            next = temp;
        }

        return root;

    }
}

Now let us test it out

Testing the logic

    public static void main(String args[]){

        LLNode root = new LLNode(1);
        LLNode second = new LLNode(2);
        root.setNextNode(second);
        LLNode third = new LLNode(3);
        second.setNextNode(third);
        LLNode fourth = new LLNode(4);
        third.setNextNode(fourth);

        System.out.println("Before");
        LLNode.printLL(root);
        System.out.println("After");
        LLNode.printLL(LLReverser.reverse(root));

    }

Output :

Before
1
2
3
4
After
4
3
2
1

Saturday, 28 December 2013

What is Android Debug Bridge (adb)?

This post is essentially dedicated to understand what Android Debug Bridge (adb) really is. How can we use it.


As we know Android has Linux kernel underneath. To execute a process via we need to provide corresponding command line command. Unless you root your android device you cannot really instal the terminal emulator application. The shell can be accessed via ADB (Android Debug Bridge) command tool.

What is Android Debug Bridge?

Android Debug Bridge (adb) is a versatile command line tool that lets you communicate with an emulator instance or connected Android-powered device. 

It is a client-server program that includes three components: 

  • A client, which runs on your development machine. You can invoke a client from a shell by issuing an adb command. Other Android tools such as the ADT plugin and DDMS also create adb clients.  
  • A server, which runs as a background process on your development machine. The server manages communication between the client and the adb daemon running on an emulator or device. 
  • A daemon, which runs as a background process on each emulator or device instance.  
A client can be you adb shell that you run or your IDE(Eclipse). As for the server you can check the status, kill it or start it through ADB command line tool utility. To check the daemon process you can simply type adb in your android terminal(if rooted).

 To get the overview of ADB refer to following picture

Where can I find ADB tool utility?

You can find the adb tool in <sdk>/platform-tools/. You can download the SDK from here.

More on ADB....

When you start an adb client, the client first checks whether there is an adb server process already running. If there isn't, it starts the server process. When the server starts, it binds to local TCP port 5037 and listens for commands sent from adb clients—all adb clients use port 5037 to communicate with the adb server

The server then sets up connections to all running emulator/device instances. It locates emulator/device instances by scanning odd-numbered ports in the range 5555 to 5585, the range used by emulators/devices. Where the server finds an adb daemon, it sets up a connection to that port. Note that each emulator/device instance acquires a pair of sequential ports — an even-numbered port for console connections and an odd-numbered port for adb connections. For example: 

Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557
and so on...


As shown, the emulator instance connected to adb on port 5555 is the same as the instance whose console listens on port 5554.

 Once the server has set up connections to all emulator instances, you can use adb commands to access those instances. Because the server manages connections to emulator/device instances and handles commands from multiple adb clients, you can control any emulator/device instance from any client (or from a script).[Source]


Usage Common Usage Examples

  1.  adb device(shows all the devices with device id the adb server is connected to)
  2. adb help( Shows adb version and all possible commands)
  3. adb start-server(To start adb server if not started already)
  4. adb kill-server(To kill adb server)
  5. adb push <local> <remote>(To push a file from local machine to remote device/emulator)
  6. adb pull <remote> <local>(To get a file from remote device/emulator to local machine)
  7. adb version(Shows version number of adb running)
  8. adb reboot(Reboots the device)
  9. adb root(Restarts the adbd daemon with root priveledges)
  10. adb backup(Used to backup your device. You can backup everything with -all argument)
  11. adb restore (Restore from a backup taken earlier).
  12. adb install (Push and Install a package)
  13. adb uninstall (Uninstall a package)
  14. adb shell(get shell access to your Android device)
Note : How to completely backup your android device has been already covered in a previous post. You can go through that post.


Related Links


Program to create Mirror image of a binary tree.

Question :

Write a Program in Java to print the mirror image of a given binary tree. Example is provided in following diagram


Solution :

Do a normal BFS traversal. In each call copy the left child's content to create right node of the mirror tree and the right child's content to create left child.

Code : 

public class TreeMirrorImageCreator {

    public static Node createMirrorImage(Node originalNode,Node mirroredNode){

        mirroredNode.setValue(originalNode.getValue());

        if(originalNode.getRight() != null){
            mirroredNode.setLeft(createMirrorImage(originalNode.getRight(),new Node(0)));
        }

        if(originalNode.getLeft() != null){
            mirroredNode.setRight(createMirrorImage(originalNode.getLeft(), new Node(0)));
        }

        return mirroredNode;

    }
}

Now lets write the code to test out this code.

    public static void main(String args[]){

        Node root = new Node(1);

        Node l = new Node(2);
        Node r = new Node(3);

        Node l1 = new Node(12);
        Node l2 = new Node(13);

        Node r1 = new Node(6);
        Node r2 = new Node(8);

        root.setLeft(l);
        root.setRight(r);

        l.setLeft(l1);
        l.setRight(l2);

        r.setLeft(r1);
        r.setRight(r2);

        System.out.println("Orig Tree : ");
        LevelTraversal.printLeveltraversal(root);
        Node mirroredRoot = new Node(0);
        TreeMirrorImageCreator.createMirrorImage(root,mirroredRoot);
        System.out.println("Mirrored Tree : ");
        LevelTraversal.printLeveltraversal(mirroredRoot);
}


Note :  Code for the Node data structure and level order traversal can be found here.

Related Links

Thursday, 26 December 2013

Deepest left leaf node in a binary tree

Question : 

Given a Binary Tree, find the deepest leaf node that is left child of its parent. For example, consider the following tree. The deepest left leaf node is the node with value 9.

Code:


 public class DeepestLeftLeafNodeFinder {

    Node deepestNode;
    int deepestNodeDepth;

    public Node findDeepestLeftLeafNode(Node root,boolean isLeftNode,int depth){

        if(isLeftNode){
            if(depth > deepestNodeDepth){
                deepestNode = root;
                deepestNodeDepth = depth;
            }
        }

        if(root.getLeft() != null){
            findDeepestLeftLeafNode(root.getLeft(),true,depth + 1);
        }

        if(root.getRight() != null){
            findDeepestLeftLeafNode(root.getRight(),false,depth+1);
        }

        return deepestNode;
    }
}

Test :

    public static void main(String args[]){

        Node root = new Node(1);

        Node l = new Node(2);
        root.setLeft(l);
        Node r = new Node(3);
        root.setRight(r);

        Node l1 = new Node(4);
        l.setLeft(l1);

        Node r1 = new Node(5);
        r.setLeft(r1);
        Node r2 = new Node(6);
        r.setRight(r2);

        Node r12 = new Node(7);
        r1.setRight(r12);

        Node r121 = new Node(9);
        r12.setLeft(r121);

        Node r22 = new Node(8);
        r2.setRight(r22);

        Node r222 = new Node(10);
        r22.setRight(r222);

        System.out.println("Deepest left node of the tree is : " +
                new DeepestLeftLeafNodeFinder().findDeepestLeftLeafNode(root,false,0).getValue());
    }

Output :

Deepest left node of the tree is : 9 

Note : Complexity of above code is O(N) as we are visiting each node at most once. Do let me know if anyone has a better solution.

Wednesday, 25 December 2013

Find next right node of a given key

Question : Find next right node of a given key

Given a Binary tree and a key in the binary tree, find the node right to the given key. If there is no node on right side, then return NULL. Expected time complexity is O(n) where n is the number of nodes in the given binary tree.
For example, consider the following Binary Tree. Output for 2 is 6, output for 4 is 5. Output for 10, 6 and 5 is NULL.




Code : 


package in.blogspot.osg.Demo;
import java.util.LinkedList;
import java.util.Queue;

public class RightNodeFinder {
    
    Queue<Node> nodeQueue = new LinkedList<Node>();
    Queue<Integer> levelQueue = new LinkedList<Integer>();
       
    public Node findRightNode(int value, Node root, int level){

        if(value == root.getValue()){
            if(nodeQueue.isEmpty()){
                return null;
            }
            else{
                if(levelQueue.peek() != level){
                    return null;
                }
                else{
                    return nodeQueue.poll();
                }
            }
        }
        else{           
            if(root.getLeft() != null){
                nodeQueue.offer(root.getLeft());
                levelQueue.offer(level + 1);
            }
            if(root.getRight() != null){
                nodeQueue.offer(root.getRight());
                levelQueue.offer(level + 1);
            }
            if(!nodeQueue.isEmpty()){
                return findRightNode(value, nodeQueue.poll(), levelQueue.poll());
            }   
        }
        return null;
    }
}

Now lets test the code. You can see the code for Node data structure in this post


    public static void main(String args[]){
        
        Node root = new Node(10);
        Node l = new Node(2);
        Node r = new Node(6);
        Node l1 = new Node(8);
        Node l2 = new Node(4);
        Node r2 = new Node(5);
        
        root.setLeft(l);
        root.setRight(r);
        l.setLeft(l1);
        l.setRight(l2);
        r.setRight(r2);
        
        System.out.println("Right Node of node with value 10 is : " + new RightNodeFinder().findRightNode(10, root, 0));
        System.out.println("Right Node of node with value 2 is : " + new RightNodeFinder().findRightNode(2, root, 0));
        System.out.println("Right Node of node with value 6 is : " + new RightNodeFinder().findRightNode(6, root, 0));
        System.out.println("Right Node of node with value 8 is : " + new RightNodeFinder().findRightNode(8, root, 0));
        System.out.println("Right Node of node with value 4 is : " + new RightNodeFinder().findRightNode(4, root, 0));
        System.out.println("Right Node of node with value 5 is : " + new RightNodeFinder().findRightNode(5, root, 0));
    }

Output : 

 

Right Node of node with value 10 is : null
Right Node of node with value 2 is : Data is : null and Value is : 6
Right Node of node with value 6 is : null
Right Node of node with value 8 is : Data is : null and Value is : 4
Right Node of node with value 4 is : Data is : null and Value is : 5
Right Node of node with value 5 is : null
t> UA-39527780-1 back to top