Showing posts with label Interview. Show all posts
Showing posts with label Interview. Show all posts

Monday, September 29, 2014

CC150 2.3 - Delete node in a singly linked list with only access to that node

For this interview question, the answer is not a common way to remove a node in  a singly linked list. Basically, you redirect the next node pointer of the previous node to the next pointer of the node you want to remove. Since you only have access to the current node, the tricky solution is you can replace current node with the next one. However, it is impossible to do that if the node is the last one of the list.
class Test2_3 {
    public static void main(String argv[]) {
        int todel = 4;
        if(argv.length > 0) {
            todel = Integer.parseInt(argv[0]);
        }
        Random rand = new Random(System.currentTimeMillis());
        // Create a list instance
        List list = new List();
        Node nodedel = null;
        for(int i = 0; i < 10; i++) {
            Node n = new Node(rand.nextInt(10));
            if(i == todel-1)  nodedel = n;
            list.attach(n);
        }
        System.out.printf("Remove %dth node of the list: ", todel);
        list.print();
        // Remove
        if(nodedel != null && nodedel.next != null) {
            Node next = nodedel.next;
            nodedel.data = next.data;
            nodedel.next = next.next;
        } else {
            System.out.println("Could not remove the last one!");
        }
        list.print();

    }
}   

Wednesday, August 13, 2014

Repeating number problem - 3


Given a (potentially large) array of integers, all but one repeating an even number of times, how would you find the one repeating an odd number of times in an efficient way? eg [1 2 3 3 2 2 1 4 2] should return 4

Method 1: Use map data structure to track the occur times of the number in the list. Then loop through the map to find the number occurs even times.
Output:
Number occur even times: 6


Method 2: Find the unique set of the integer array and append the unique set to the original array. Then XOR the new array leaving only the number repeat even times. The trick is XOR with odd times itself remains zeros, XOR with even times itself remains itself.
Output:
Number that occurs even times: 6

Repeating number problem - 2

Given an array in which all numbers except two are repeated once. (i.e. we have 2n+2 numbers and n numbers are occurring twice and remaining two have occurred once). Find those two numbers in the most efficient way.

Method 1: Use xor operators only to find the two non duplicate numbers. Xor all (2n+2) numbers first, then the n duplicate numbers are cancelled out, leaving the two unique number being XORed. The set bits in the result indicate bits at which the two numbers differ. The bit in a specific position can be either set or clear. Correspondingly, we can divide the numbers into set group numbers and clear group numbers w.r.t the set/diff bits in the result. Since all the other numbers repeat once, it doesn't change the XORed result either in the set group or the clear group. Thus, the XOR of set group and clear group are the two numbers occurred only once.
To divide numbers into set and clear group, we need to extract the set/diff bit of all 2n+2 numbers, here is the way to extract the right most diff/set bit of the XOR result of all 2n+2 numbers.
int diffBitMask = xor & ~(xor-1);
xor-1 zero the right most set bit and keep the other set bits. The complement operator ~ mask off the other set bits and set the right most one.

The code is as follows:
public class Main {
    public static void main(String args[]) {
        int arr[] = {1, 2, 6, 1, 6, 8, 7, 8};
        findNonDuplicate(arr);
    }
    public static void findNonDuplicate(int arr[]) {
        int xor = 0, xor1 = 0, xor2 = 0;
        // Xors of the all numbers, obtaining the difference mask of two numbers
        for(int i = 0; i < arr.length; i++) {
            xor ^= arr[i];
        }
        int diffBitMask = xor & ~(xor-1);   // Right most set/diff bit
        // Grouping based on the diff bit
        for(int i = 0; i < arr.length; i++) {
            if((arr[i] & diffBitMask) > 0) {
                xor1 ^= arr[i];
            } else {
                xor2 ^= arr[i];
            }
        }
        System.out.println("The two numbers that occur once are: " + xor1 + ", " 
                + xor2);
    }
}   
Output is:
The two numbers that occur once are: 7, 2


Repeating number problem - 1

Here is the collection of problems that related to finding  the duplicate numbers in a array.

1. Given an array of numbers ranging from 1 to N, in which numbers could repeat itself any number of times, find the duplicate numbers in O(n) with constant memory space.

Method 1: Use an extra array keep track of the elements counting.

public class Duplicate {
    public static void main(String args[]) {
        int arr[] = {1, 3, 5, 8, 5, 7, 4, 2, 4};
        findDuplicate(arr);

    }
    public static void findDuplicate(int arr[]) {
        // Using the current number as the key/index to the value
        for(int i = 0; i < arr.length; i++) {
            // Positvie - never seen before
            if( arr[Math.abs(arr[i]) - 1] > 0 )  {
                arr[Math.abs(arr[i]) - 1] =  -arr[Math.abs(arr[i]) - 1];
            }
            // Negative - already seen, duplicate 
            else if(arr[Math.abs(arr[i]) - 1] < 0) {
                System.out.print(Math.abs(arr[i]) + " ");
                arr[Math.abs(arr[i]) - 1] = 0;
            }
            else {// 0 - already detected
            }
        }
        System.out.println();
    }
}
output:
5 4