Two Sum Problem

Problem description:

Given an array of integers, find two numbers such that they add up to a specific target number.

Your function should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

Solution:

There exist a very obvious quadratic solution, you would just need to loop through the array and for each i element loop from i +1 to n to look for the number which gives you a sum so that array[i] + array[j] = target. This approach works just fine but the problem is that it’s too slow, it runs in quadratic time O(n^2), could we do it better? Yes.

An optimized solution is to use an additional data structure which allows us to keep track of each number that we have and also its index, for this task we could use a HashMap which offers a constant time look-up operation, so we just need to loop the array once to store the elements and their corresponding indices in our HashMap and then loop through the array again and for each element i just check if hashmap.containsKey(target – array[ i ]). Here is the working solution implemented in Java:


public int[] twoSum(int[] numbers, int target) {
        
    HashMap<Integer, Integer> indexes = new HashMap<Integer, Integer>();
        
    for(int i = 0; i < numbers.length; ++i) {
        indexes.put(numbers[i], i);
    }
            
    for(int i = 0; i < numbers.length; ++i) {
        if(indexes.containsKey(target - numbers[i])) {
            return new int[]{i + 1, indexes.get(target - numbers[i]) + 1};
        }
     }
    return null;
}

This solution is much faster than the first approach, this runs in linear time (considering that HashMap look-up operation runs in constant time).

Check if a string has all unique characters without using extra space

Given a string, check if all its elements are unique, it means, there are no repeated characters.

example:

HELLO -> not all its characters are unique since character ‘l’ appears twice.

WORLD -> has all unique characters

This problem has many possible solutions, and to make it more interesting let’s suppose we are not allowed to use any extra data structure (a few extra variables are allowed but an entire copy of the array is not).

Solution.

Approach 1: Quadratic solution

The idea is to loop through the string an compare each element to the ones that we know they are unique so far, it could be done with the code below:

static boolean checkUniqueCuadratic(char arr[])
{
    int point = 0; //all elements before this point are unique for sure

    for(int i = 0; i < arr.length; ++i) // for each element, we are gonna compare to each unique element
    {
        char c = arr[i];

        for(int j = 0; j < point; ++j)
        {
            if(c == arr[j]) {
                return false;
            }
        }
        ++point; // at this time we now have a new unique element
    }
    return true;
}

Note that the solution above runs in quadratic time O(n^2) since it has two nested loops. We could probably just keep a data structure that allows us to keep of which elements we have visited and then just check if the ith element is within our helper data structure in just one loop, but remember we are not allowed to use any additional data structure.

Approach 2: “linearithmic” solution (n log n in time complexity)

Another good approach and actually faster is to sort the string by using any in place sorting algorithm which guarantees n log n in time complexity (like quicksort) and then just loop through the string and check if the next element equals the current element. The code below shows the implementation of this approach:


import java.util.*;

public class UniqueChars
{
    public static void main(String... args)
    {
        Scanner sc = new Scanner(System.in);

        while(sc.hasNextLine())
        {
            char line[] = sc.nextLine().toCharArray();
            quicksort(line, 0, line.length - 1);// sort the string by using quicksort
            System.out.println(checkUnique(line));
        }
    }

    static boolean checkUnique(char arr[])
    {
        for(int i = 0; i < arr.length - 1; ++i)
            if(arr[i] == arr[i + 1])
                return false;

        return true;
    }

    /*
       Basic quicksort implementation
    */
    static void quicksort(char array[], int a, int b)
    {
        if(b - a < 1)
            return;

        int pivot = a;
        int i = a + 1;
        int j = b;

        while(i < j)
        {
            while(array[i] < array[pivot] && i < b) i++;
            while(array[j] > array[pivot] && j > a) j--;

            if(i < j)
                interchange(array, i, j);
        }
        interchange(array, pivot, j);

        quicksort(array, a, j - 1);
        quicksort(array, j + 1, b);
    }

    static void interchange(char arr[], int a, int b)
    {
        char temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

You have any comment/suggestion/question? please let us know!!

Rotate a matrix by 90 degrees

Problem description: Given an N X N integer matrix, rotate it bye 90 degrees in place.
eg.

[1,  2, 3, 4]                   [9, 6, 9,  1]
[9, 8, 5, 6]         –>       [2, 5, 8, 2]
[6, 5, 3, 7]                    [6, 3, 5, 3]
[9, 2, 6, 8]                    [8, 7, 6, 4]

Solution:

The key is to solve this problem in “layers” from outer ones to inner ones as follows:

In our example we have two layers:

OUTER LAYER          INNER LAYER
1 2 3 4
9       6                               8 5
6       7                               5 3
9 2 6 8

The idea is to do a “four-way” swap variable, we need to move the values from top -> right, right -> bottom, bottom -> left and left -> top, can we do it by using only one extra variable? Yes, we can.

At each layer we are gonna loop through the elements and swap them as follows:
1.- Save the ith element in the top array in a temporary variable (in our example the top array is [1 2 3 4] ).
2.- Move the ith element from left to top.
3.- Move the ith element from bottom to left.
4.- Move the ith element from right to bottom.
5.- Save the value of our temporary variable in the ith position in the right array.

Here is the code in Python:

#!/usr/bin/python -tt

import sys

#create a N X N matrix
def getMatrix(n):
    matrix = []
    for i in range(n):
        inside = []
        for j in range(n):
            inside.append(j + i + 2)
        matrix.append(inside)
    return matrix

#print the matrix
def printMatrix(m):
    for row in m:
        print row
    print

#rotate the matrix by 90 degrees (clockwise) in place
def rotate90Degrees(m):
    layers = len(m) / 2
    length = len(m) - 1

    for layer in range(layers): #for each layer
        for i in range(layer, length - layer): # loop through the elements we need to change at each layer
            temp = m[layer][i] #save the top element, it takes just one variable as extra memory
            #Left -> Top
            m[layer][i] = m[length - i][layer]
            #Bottom -> left
            m[length - i][layer] = m[length - layer][length - i]
            #Right -> bottom
            m[length - layer][length - i] = m[i][length - layer]
            #Top -> Right
            m[i][length - layer] = temp

#main function
def main():
    #it takes values from stdin
    for line in sys.stdin:
        n = int(line)
        print "N = "+ str(n)
        matrix = getMatrix(n)
        print "Original matrix:\n"
        printMatrix(matrix)
        rotate90Degrees(matrix)
        print "Rotate matrix by 90 degrees:\n"
        printMatrix(matrix)

if __name__ == '__main__':
    main()

Some input/output samples:

N = 4
Original matrix:

[2, 3, 4, 5]
[3, 4, 5, 6]
[4, 5, 6, 7]
[5, 6, 7, 8]

Rotate matrix by 90 degrees:

[5, 4, 3, 2]
[6, 5, 4, 3]
[7, 6, 5, 4]
[8, 7, 6, 5]
************************************
N = 2
Original matrix:

[2, 3]
[3, 4]

Rotate matrix by 90 degrees:

[3, 2]
[4, 3]
*************************************
N = 5
Original matrix:

[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
[6, 7, 8, 9, 10]

Rotate matrix by 90 degrees:

[6, 5, 4, 3, 2]
[7, 6, 5, 4, 3]
[8, 7, 6, 5, 4]
[9, 8, 7, 6, 5]
[10, 9, 8, 7, 6]

Square root of a number without using any built-in function

Problem description:

Given a number N, compute the square root.

Solution:

Alright, I know that every programming language has a built-in function to compute the square root of a number and of course that’s what you’re gonna use in a normal situation. But what if you are asked to solve this problem in a programming interview and you are not allowed to use any built-in function?

Well, to solve this problem we need to find a number which multiplied by itself becomes our given N, the simplest way to do it would be to loop from zero to N multiplying each number by itself and verifying if it equals N, but if we think about it for a while we  realize we can do it much faster, how?… Binary Search!.

Let’s explain this algorithm with a basic example, let’s say we want to compute the square root of 9.

We have our range of possible square roots: 0 to 9

1.- The idea is to get the middle element in our range: 9 + 0 / 2 = 4.5

2.- multiply it by itself: 4.5 * 4.5 let’s call this new value P = 20.25

3.- verify if P equals N, if it does then we have found the square root of N, if not…

4.- Now we have two possibilities:

– P is greater than N: in this case we are gonna modify our range of possibilities because we know all numbers greater than 4.5 are not the square root, so now our range of possible square roots are between 0 and 4.5

– P is less than N: This is the opposite, so we would modify our lower bound instead of the upper bound.

We are going to repeat these steps until we find the square root of N.

Below you can find the code for this solution in Python.

#!/usr/bin/python -tt

import sys

def sqrt(n):
    start = 0
    end = n
    m = 0
    min_range = 0.0000000001;
    
    while end - start > min_range:
        m = (start + end) / 2.0;
        pow2 = m * m
        if abs(pow2 - n) <= min_range:
            return m
        elif pow2 < n:
            start = m
        else:
            end = m
            
    return m

def main():
    for line in sys.stdin:
        n = int(line)
        print sqrt(n)

if __name__ == '__main__':
    main()

Optimized Fibonacci sequence

Hi everyone,

Today I’m gonna share the solution for one of the most famous programming interview problems, given a number n, write a program to get the nth element of the Fibonacci sequence.

Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, … where the first two numbers are 0 and 1, and each subsequent number is the sum of the previous two.

Here there’s an obvious recursive solution:

int fibo(n)
{
    if n<=2:
        return 1;
    else:
        return fibo(n-1) + fibo(n-2);
}

it works fine for a very small n ( <= 30), but what if we need to compute the 10,000th element of the sequence?

Solution:

First of all I want to explain why the above algorithm doesn’t work for a big n, let’s illustrate how it works as a recursion tree:

let’s say we need to get the 5th element of the sequence, so we have:

fib_5

As you can see, there are a bunch of overlapping calls to fibo, actually this algorithm is O(2^n) in time complexity because to get the nth element of the sequence we need to compute all the n-1 elements and for each one we have two recursive calls… it’s just too slow!

Now, with a very small modification we can improve the efficiency of this program, it’s basically adding a “cache” table for our “already known” results, let’s take a look at the code (in Python):

#!/usr/bin/python -tt

memo = {}

def main():
    f = open("data.in","r")
    for line in f:
        print fibo(int(line))

def fibo(n):
    if n <= 2:
        return 1
    if n in memo:
        return memo.get(n)

    memo[n] = fibo(n - 1) + fibo(n - 2)
    return memo[n]

if __name__ == '__main__':
  main()

memo is a hashtable where we store the results for each fibo function call, so if we compute fibo(5), we don’t need to re-compute fibo(5) in the future because we already have the result in our memo table 🙂 so now we can compute fibo(10000) in just fractions of millisecond and this is because now our program runs in O(n).

Number to its equivalent english phrase problem.

Given a floating point number (that represents money), print an English phrase which describes that quantity of money.

eg. 1234.39 -> one thousand two hundred thirty four dollars and thirty nine cents

This particular problem is one of those problems that are not that hard but are just so tedious, this problem is also very common in programming interviews so check out my solution and make sure you understand how it works.

Solution:

The key is to realize that there is a pattern, each three digits we have the same structure:

hundreds – tens – digits

so we can build our string as follows

23,456,792 -> convert(23) + ” million ” + convert(456) + ” thousand ” + convert (792) + ” ”

code:

import java.util.*;

public class NumberToString
{
	static final String thous[] = new String[]{"","thousand"};
	static final String bigs[] = new String[]{"","million", "billion"};
	static final String numbers[] = new String[100];

	public static void main(String... args)
	{
		numbers[1] = "one";
		numbers[2] = "two";
		numbers[3] = "three";
		numbers[4] = "four";
		numbers[5] = "five";
		numbers[6] = "six";
		numbers[7] = "seven";
		numbers[8] = "eight";
		numbers[9] = "nine";
		numbers[10] = "ten";
		numbers[11] = "eleven";
		numbers[12] = "twelve";
		numbers[13] = "thirteen";
		numbers[14] = "fourteen";
		numbers[15] = "fifteen";
		numbers[16] = "sixteen";
		numbers[17] = "seventeen";
		numbers[18] = "eighteen";
		numbers[19] = "nineteen";
		numbers[20] = "twenty";
		numbers[30] = "thirty";
		numbers[40] = "forty";
		numbers[50] = "fifty";
		numbers[60] = "sixty";
		numbers[70] = "seventy";
		numbers[80] = "eighty";
		numbers[90] = "ninety";
		Scanner sc = new Scanner(System.in);
		while(sc.hasNextDouble())
			System.out.println(convert(sc.nextDouble()));

	}
	static String convert(double n)
	{
		long decimals = getDecimals(n);
		long integer = (long) n;
		String result = "";
		int count = 0;
		int count2 = 0;

		if(integer == 0)
			result = "zero ";

		while(integer > 0)
		{
			long chunk = integer % 1000000;
			count = 0;
			boolean add = chunk > 0;
			String t = "";

			while(chunk > 0)
			{
				String temp = convertDigits(chunk % 1000);

				if(!temp.isEmpty())
					t = temp + thous[count] + " " + t + " ";

				count++;
				chunk /= 1000;
			}

			if(add)
				result = t.trim() + " " + bigs[count2] + " " + result + " ";

			integer /= 1000000;
			count2++;
		}

		String cents = convertDigits(decimals) +"cents";

		return result.trim() + " dollars " + (decimals > 0 ? "and " + cents : "");
	}
	static String convertDigits(long num)
	{
		String result = "";

		if(num / 100 > 0)
			result += numbers[(int)(num / 100)] + " hundred ";

		num = num % 100;

		if(num  0)
		{
			result += numbers[(int)num]+" ";
			return result;
		}

		if(num / 10 > 0)
			result += numbers[(int)(num/10 * 10)]+" ";

		num = num % 10;
		if(num > 0)
			result += numbers[(int)num]+" ";

		return result;
	}
	static long getDecimals(double n)
	{
		return (long) (n * 100.0) % 100;
	}
}