Sunday, April 9, 2017

Find number of islands from a give 2D matrix of 0s and 1s

For a given 2D matrix of 0s and 1s, find number of islands where an island is defined as number of 1s together. For example for a 2D matrix below:
0,1,1,0
0,1,1,0
0,0,0,0
1,1,0,0

Number of islands is 2.

Solution is going to O(m*n) where m and n are number or rows and columns of the matrix respectively.

    int numIslands(int [][]a) {
        if (a == null || a.length == 0 || a[0].length == 0) {
            return 0;
        }

        int rows = a.length;
        int cols = a[0].length;
        boolean[][]b = new boolean[rows][cols];
        int counter = 0;

        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                if (a[i][j] == 1 && !b[i][j]) {
                    counter ++;
                    visitIsland(a, b, i, j);
                }

        return counter;
    }

    void visitIsland(int[][]a, boolean[][]b, int i, int j) {
        if (a == null || b == null
                || a.length == 0 || b.length == 0
                || a[0].length == 0 || b[0].length == 0
                || i < 0 || j < 0 || i == a.length || j == a[0].length)
            return;

        b[i][j] = true;

        if (i + 1 < a.length && a[i+1][j] == 1 && !b[i + 1][j])
            visitIsland(a, b, i + 1, j);

        if (j + 1 < a[0].length && a[i][j+1] == 1 && !b[i][j+1])
            visitIsland(a, b, i, j + 1);

        if (i - 1 >= 0 && a[i-1][j] == 1 && !b[i - 1][j])
            visitIsland(a, b, i - 1, j);

        if (j - 1 >= 0 && a[i][j-1] == 1 && !b[i][j-1])
            visitIsland(a, b, i, j-1);
    }

Sunday, April 2, 2017

Finds unique value from a sorted array that has duplicates such as [1,1,2,2,3,3]

    /**
     * Finds unique value from a sorted array that has duplicates such as [1,1,2,2,3,3]<br/>
     * The approach is to have a O(log n) algorithm - perform operation as a binary search
     * @param a
     * @return
     */
    public static int findUnique(int []a) {
        if (a == null || a.length == 0) {
            throw new RuntimeException("Invalid parameter");
        }

        int length = a.length;
        if (length %2 == 0) return Integer.MIN_VALUE;

        // If only single element array, return the element
        if (length == 1) return a[0];

        // This is to handle the case when the unique element is either first or last.
        if (a[0] != a[1]) return a[0];
        if (a[length - 1] != a[length - 2]) return a[length - 1];
     
        int s = 0, e = length - 1;

        // Else perform binary search
        for (; s < e;) {
            int m = (s + e) / 2;
            int mid = a[m];

            if (m == s || m == e) return mid;

            if (mid == a[m ^ 1]) {
                s = m + 1;
            } else {
                e = m;
            }
        }

        return a[s];
    }

Find permutations of a string

import java.util.*;
public class Permutation {
    public static void main(String[] args) {
        Permutation s = new Permutation();
        List<String> list = s.permutation("abc");
        System.out.println(list);

    }

    /**
     * Function that returns a list of all permutations of a word<br/>
     * The logic is that:<br/>
     * First remove the first character.<br/>
     * Find the permuatations of remaining word.<br/>
     * For each of those words, put the the first character at every location<br/>
     * Return the final list
     * @param word
     * @return List
     */
    public List<String> permutation(String word) {
        if (word == null || word.length() == 0) {
            return new ArrayList<String>();
        }

        // If word is of single character, create a list and return
        if (word.length() == 1) {
            return Arrays.asList(word);
        }

        // Recurse until we get list of single character word list
        List<String> w = permutation(word.substring(1));

        // Fetch first character of original word
        Character ch = word.charAt(0);

        List<String> result = new ArrayList<String>();

        // Iterate over the list returned as part of recursion and append to each character of the words in the list.
        for(String s : w) {
            result.addAll(append(s, ch));
        }

        // Return the resultant string
        return result;
    }


    private List<String> append(String s, Character ch) {
        if (s == null) {
            return new ArrayList<String>();
        }

        if (ch == null) {
            return Arrays.asList(s);
        }

        // Iterate over the string and append character at each point in the string
        // Note that since we will have to append to the end, hence we will have to special case the last character too.
        List<String> result = new ArrayList<String>();
        for (int i = 0; i <= s.length(); i++) {
            String temp = s.substring(0,i) + String.valueOf(ch);
            if (i < s.length()) {
                temp += s.substring(i);
            }

            result.add(temp);
        }

        return result;
    }


}