algorithm to reverse a string array in O(n/2) complexity

This problem is a subcase of ‘reversing words of a string‘.

There are many ways of reversing a string but best possible case should be considered keeping space and time complexities in mind. Complete source code can be downloaded from here.

Steps to solve this algorithm

  • take two pointers, one pointing to the start of the array and another to the end of the array and swap the values at respective pointers.
  • While traversing the array increment starting pointer and decrement ending pointer and continue swap the values at respective pointers
  • continue this till we reach the middle of the array

by this time array will be reversed as

'welcome to coding algorithms' would become 'smhtirogla gnidoc ot emoclew'

Psuedocode for O(n/2) complexity:

    /**
	 * Algorithm to reverse a string
	 * @param arr
	 * @param wordIdx
	 * @param wordMidIdx
	 * @param wordLastIdx
	 * 
	 * @return reversed string array
	 */
	public char[] reverse(char[] arr, int wordIdx, int wordMidIdx,
	        int wordLastIdx) {
	    for (; wordIdx < wordMidIdx; wordIdx++) {
	        // swap first letter with the last letter in the
	        char tmp = arr[wordIdx];
	        arr[wordIdx] = arr[wordLastIdx - 1];
	        arr[wordLastIdx - 1] = tmp;
	        wordLastIdx--;
	    }
	    return arr;
	}

Output is: smhtirogla gnidoc ot emoclew

Space Complexity: No additional space is required as we are just swapping the letters within the same array
Time Complexity: Order of this algorithm: O(n/2), where is ‘n’ is the length of the input array

O(2n) Complexity
We can use character array stack also to do this operation but to build the stack we need O(n) time and to dump the stack which print the char array in reverse order will take O(n) order.

Complete source code can be downloaded from here.

Note: how to build stack can be looked at here

print single linked list in reverse order

This is frequently asked question as we would be having only forward reference but not the backward reference to traverse the single linked list (SLL) in backward direction.

We can do this in two different ways

  • Recursive Way: Using recursion we can traverse the list in backward direction because when we recursively traverse SLL in forward direction all the method calls are kept on the stack which will be revisited in the same order but in reverse direction till the base condition is met.
  • Linear programming by using stack implementation.

Recursive Way

	public void reverse(Node node) {
		if (node != null) {
			reverse(node.next);
			System.out.print("  " + node.value);
		}
	}

Linear Programming:

	public void reverse1(Node node) {
		Deque<Node> stack = new ArrayDeque<Node>();
		while (node != null) {
			stack.push(node);
			node = node.next;
		}
		// print the stack
		while (!stack.isEmpty())
			System.out.println(stack.poll().value);
	}

Full Source Code

package algorithms.lists;
import java.util.ArrayDeque;
import java.util.Deque;

public class SLLReverse {
	private static Node root, tmp;

	public void reverse(Node node) {
		if (node != null) {
			reverse(node.next);
			System.out.print("  " + node.value);
		}
	}

	public void reverse1(Node node) {
		Deque<Node> stack = new ArrayDeque<Node>();
		while (node != null) {
			stack.push(node);
			node = node.next;
		}
		// print the stack
		while (!stack.isEmpty())
			System.out.println(stack.poll().value);
	}

	public void insert(Node n) {
		if (root == null) {
			root = n;
			tmp = root;
		} else {
			tmp.next = n;
			tmp = n;
		}
	}

	public static void main(String[] str) {
		SLLReverse s = new SLLReverse();
		// build the SLL
		for (int i = 0; i < 10; i++) {
			s.insert(new Node(i));
		}

		// print SLL in reverse order
		s.reverse1(s.root);
	}

	static class Node {
		Node next;
		int value;

		Node(int i) {
			value = i;
		}
	}
}

order of hashmap/hashtable in BIG-O Notation

Order or complexity of any hash implemented data structure in java is O(1).

O(1)  means the time to retrieve an element from the data structure is always almost equals to constant. However poor implementation of hashing can lead to the complexity of O(n).

In O(1) complexity, the elements of the data structure are distributed across the buckets evenly.

In O(n) complexity, the elements of the data structure are all stored in one bucket (very poor hashing implementation).

Note: However SUN will revisit the user given hash code to avoid O(n) complexity, to get more into the details look at detailed hashmap implementation

best searching algorithm

Consider a data structure, say, array ‘a’ of size m

  1. Linear Search with complexity O(n)
  2. Binary Search with complexity O(log n)
  3. Search using HASH value with complexity O(1)

Linear Search with complexity O(n):
Here for a given element, say a[i],  we have to traverse the entire data structure till we find the element, so in the worst case we have to traverse till end of the DS and hence the order/complexity of linear search is O(n)

This is a brute force way of doing it.

pros:
suitable for smaller sized data structures
suitable for data structures which are not sorted
simpler approach, simple and less code (KISS principle)

cons:
for large sized data structures this wont do any good in terms of time complexity

Binary Search with complexity O(log n):
Binary search implements divide and conquer algorithm to search for a required element in the data structure. But to do a binary search on the data structure(DS), DS elements needed to be in sorted manner. (see best sorting algorithms)

Every iteration we divide the array by 2 and then see which side the element (to be searched) falls (lower half or upper half) and recursively do the same thing till the element is found.

logarithm is just a mathematical scale to represent number system in powers of base, in binary search case, base=2 (because every time we divide the DS by two in one way also implies raising the power by 2 in other way)

Example:
1,3,5,7,10,12,16,19
Here we have 8 elements, so every time we divide by half, we can pin point to any element within three iterations, that is, lets assume we are searching for ’19’

First Iteration:
step 1:   pivot = a[(0+7)/2) = a[3] = 7
step 2: Since 19>7, ignore left side of pivot and consider right side array of pivot, that is, 10,12,16,19

Second Iteration:
step 1:   pivot = a[(0+3)/2) = a[1] = 12
step 2: Since 19>12, ignore left side of pivot and consider right side array of pivot, that is, 16,19

Third Iteration:
step 1:   pivot = a[(0+1)/2) = a[0] = 16
step 2: Since 19>16, ignore left side of pivot and consider right side array of pivot, that is, 19, return this value

hence number of elements =8=2^3=3(in log with base 2 scale), therefore the complexity of binary search algorithm is O(log n)

/**
* @author ntallapa
*
*/
public class BinarySearch {

	/**
	 *
	 * @param a integer array to be searched
	 * @param value element of the array to be searched
	 * @param left left most index of the passed array
	 * @param right most index of the passed array
	 * @return element value if found else -1 if not found
	 */
	public int binarySearch(int[] a, int value, int left, int right) {

		// choose pivot index element as middle element
		int idx = (left+right)/2;

		// check if pivot index exists in the array
		if(idx>=a.length) {
			return -1;
		}
		int pivot = a[idx];

		if(left > right)
			return -1;

		if(value < pivot) {
			right = idx-1;
			return binarySearch(a, value, left, right);
		} else if(value > pivot) {
			left = idx+1;
			return binarySearch(a, value, left, right);
		} else {
			return pivot;
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] a = {1,2,3,4,5};
		BinarySearch bs = new BinarySearch();

		System.out.println(bs.binarySearch(a, 3, 0, a.length));
	}
}

pros:
Best suitable for large sized arrays

cons:
array elements must be sorted prior to search

Search using HASH value with complexity O(1): 
Insert the elements of the data structure into a hash implemented data structure like Hashtable or HashMap and you are good to go with one line statement:
hashArr.contains(a[i])
Since the elements of hashmap are indexed by hashcode, the time to search for any particular element would almost be = 1 (CONSTANT time)

pros:
Best in case of medium-large sized arrays

cons:
If the array is very large then it might lead to collisions in the hash implemented DS
Additional space requirements to store array elements into hashmap

WHICH ONE TO USE:
It is actually a trade off between these three approaches on which one to use. There is never always one best approach to follow blindly. We should analyze the scenario and adopt one of these.

Matrix Search – find group of connected-1s/sectors in a matrix

find length of connected cells of 1s(sector) in an matrix of 0s and 1s?
find number of islands in a matrix?
find connected sectors of a matric?
implementation of flood fill algorithm?
All these questions are same, below are the implementation details

Full source code can be downloaded from here

Consider a two-dimensional grid of cells, each of which may be empty or filled. The filled cells that are connected form a sector. Two cells are said to be connected if they are adjacent to each other horizontally, vertically or diagonally. There may be several sectors on the grid. Your job is to find the largest sector (in terms of number of cells) on the grid.

The following figure illustrates a grid with 3 sectors (the largest contains 5 cells).
grid

Problem
Write a program that determines the size of the largest sector for a given grid.

Input
The input begins with a single positive integer on a line by itself indicating the number of the cases
following, each of them as described below. This line is followed by a blank line, and there is also a blank
line between two consecutive inputs. The grid is given as a set of string, each composed of 0s and 1s.
The 1 indicates that the cell is filled and 0 indicates an empty cell. The strings should be converted into
the grid format. The largest grid that should be considered is a 25×25 grid.

Attached is the input file:
input.txt

Output
For each test case, the output must follow the description below. The outputs of two consecutive cases
will be separated by a blank line. The output is the size of the largest sector found on the grid.

Sample Input
2

11000
01100
00101
10001
01011

1011
1010

Sample Output
5
3

This solution is a recursion of depth of 8 levels :

int findMaxDepth(int[][] n, boolean[][] bool, int i, int j) {
	// Check if i, j (indexes) are within the size of array
	// Check if the cell is already traversed or not using bool array
	// Check if the cell value is 1 before counting it as part of a sector
	if(i >= 0 && i < n.length &&  				j >=0 && j < n[0].length
				&& bool[i][j] != true && n[i][j] != 0) {
		currentDepth++;

		// Mark the status of the cell for backtracking purpose
		bool[j] = true;

		// left traversal
		findMaxDepth(n, bool, i-1, j);
		// right traversal
		findMaxDepth(n, bool, i+1, j);

		// top traversal
		findMaxDepth(n, bool, i, j-1);
		// bottom traversal
		findMaxDepth(n, bool, i, j+1);

		// Top-Bottom diagnol
		// diagnol-down traversal
		findMaxDepth(n, bool, i+1, j+1);
		// diagnol-up traversal
		findMaxDepth(n, bool, i-1, j-1);

		// Bottom-Top diagnol
		// diagnol-down traversal
		findMaxDepth(n, bool, i+1, j-1);
		// diagnol-up traversal
		findMaxDepth(n, bool, i-1, j+1);
	}
	return currentDepth;
}

Full source code can be downloaded from here

Attaching the problem statement, input.txt.
counting_cell
 

Java Naming and Directory Interface (JNDI), JNDI Architecture

 

Naming Service? Is a service which allows us to store and retrieve simple objects with a unique name. It is just like one of the storage unit.

Directory Service? Is an added service on top of naming service which allows us to store and retrieve objects with some directory names (i.e, maintained into groups)

These services are implemented by different vendors where each vendor provides their own APIs and protocols to interact with theirs naming and directory services.
If any java application wants to use these services, it has to plugin to any of the vendor provided implementation, then

  • Application becomes vendor specific
  • While deploying we need to know about the vendor and its service API
  • While migrating the application from one vendor to another we need to change the code base of the application

To avoid these problems we want a standard abstraction through which a java application can interact with any vendor implemented Naming and Directory Service. To meet the above requirement SUN has released standard API providing solution to the above mentioned problems. These standards have been released under JNDI (Java Naming and Directory Service)

JNDI is an standard abstraction which allows any java application to interact with any vendor implemented naming and Directory Service.

In this case if java application wants to interact with any naming registry it just requires to prepare a request in JNDI format using JNDI API i.e, request is explained and submitted to JNDI API classes where JNDI API uses the information given by the java application and locates the SPI implementation and initializes it.
JNDI API dispatches the request to the SPI implementation through JNDI SPI.

SPI implementation converts the request and interact with the respective registry to process the request, collects the response convert it into the JNDI format and return it.
JNDI API returns response to the java application.

JNDI API
javax.naming.Context
Is an interface given under JNDI specification. Declared with methods required to read, insert, update and remove the objects like lookup, bind, rebind, unbind, list

This interface should be implemented by the vendors as part of SPI implementation.

javax.naming.InitialContext
Is a non-abstract class implementing Context interface given under JNDI specification. It implements wrapper pattern, it wraps one context implementation instance (i.e, instance of context interface implementation class given by third party vendor)
This is given to simplify the process of locating and initializing SPI implementation objects. i.e, it separates logic required to locate and initiaze SPI implementation objects from java objects.

Using JNDI API to connect to the naming registry

  • Set the required properties like
    a. Name: Context.INITIAL_CONTEXT_FACTORY
    Value: should be the qualified class name of the implementation class of javax.naming.spi.InitialContextFactory interface
    Example: weblogic.jndi.WLInitialContextFactory is the implementation class name of javax.naming.spi.InitialContextFactory. This allows us to interact with weblogic naming registry
    b. Name: Context.PROVIDER_URL
    Value: should be the url pointing to the naming registry
    Example: t3:\\localhost:7001 : points to weblogic naming registry running on the local machine on 7001 port.
    These properties can be set into the system properties into hashtable
  • Create an instance of InitialContext (IC) where it has following constructors
    a. IC as no arguments: In this case it gets the properties from the system props object
    b. IC(Hashtable ht): It gets the properties from hashtable
    Note: The first property given under the step1 is mandatory and if it is not found, IC object will not be created and it throws NamingException describing NoInitialContextFoundException

Step 1:

Hastable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,  “weblogic.jndi.WLInitialContextFactory”);
ht.put(Context.PROVIDER_URL, “t3:\\localhost:7001”);

//Here t3 is weblogic specific protocol
InitialContext ic = new InitialContext(ht);

Step 2:

System.setProperty(Context. INITIAL_CONTEXT_FACTORY,  “weblogic.jndi.WLInitialContextFactory”);
System.setProperty(Context.PROVIDER_URL, “t3:\\localhost:7001”);
InitialContext ic = new InitialContext(ht);

The above steps connects to the naming registry, now we can use IC object reference and interact with the naming registry to get the object and store the object.

 

Mawazo

Mostly technology with occasional sprinkling of other random thoughts

amintabar

Amir Amintabar's personal page

101 Books

Reading my way through Time Magazine's 100 Greatest Novels since 1923 (plus Ulysses)

Seek, Plunnge and more...

My words, my world...

ARRM Foundation

Do not wait for leaders; do it alone, person to person - Mother Teresa

Executive Management

An unexamined life is not worth living – Socrates

javaproffesionals

A topnotch WordPress.com site

thehandwritinganalyst

Just another WordPress.com site

coding algorithms

"An approximate answer to the right problem is worth a good deal more than an exact answer to an approximate problem." -- John Tukey