Friday, April 27, 2018

Convert a Decimal Number into Binary Representation

This is very easy to implement.

Principle to Convert

A decimal number is converted into binary number by repeatedly dividing the number by 2 and prepending the remainder. So the first remainder is placed at Unit Place, Second remainder at Tens Place, Third remainder at Hundreds Place and so on.







Saturday, April 21, 2018

MIT Open Courseware - Introduction to Algorithms (2008)

This is just a bookmarks to MIT Open Courseware Course 6.006 (Introduction to Algorithms (2008)). Following are the links to the course pages:






Binary Search, Limit Search, Bound Search and Range Query

Binary Search

Binary Search is the most efficient algorithm for searching in sorted array.

Implementation of Binary Search is pretty straightforward.

Lower Limit and Upper Limit

Binary search in a sorted list is straight forward. Binary search principle can also be applied to search for the lower limit and upper limit.

Lower Limit means the minimum index item, which is greater than or equal to the given search item.

Similarly, Upper Limit means the maximum index item, which less than or equal to the given search item.

Lower Limit

Upper Limit

Lower Bound and Upper Bound

Lower Bound means the minimum index item, which is greater than given search item.

Similarly, Upper Limit means the maximum index item, which less than given search item.

Lower Bound

Upper Bound

Test

Application of Limit Search

There can be several applications of these. One of the application could be using the lower and upper limit to find the number of items in the given range.







Sunday, April 15, 2018

Template File for Sublime Text - Customization

It is always easy to have file templates when we need have them created repeatedly. Today I am going to show file templates in Sublime Text 2.

SublimeFileTemplates - Installation and Usage

To create a file using a template, I have used Sublime File Templates Package for the Sublime Text. Installation and Usage is explained in the GitHub page of the package.

When you install the package, by default, some templates will be installed for some of the file types. If you are not satisfied with the default template, you have an option to customize it.

Here I am going to explain the template customization for the file type *.java

Template Customization for Java

You can locate the templates files for file types at
  • ~/Library/Application Support/Sublime Text 2/Packages/FileTemplates/Templates (Unix)
  • C:/Users//AppData/Roaming/Sublime Text 2/Packages/FileTemplates/Templates (windows)
There you can find template settings file - java.file-template and actual template file - java.java.

java.file-template

This file looks like
Here you can add as much arguments as you need, they will be asked in the order specified and can be used in the template file.

java.java

This is actual template file. When you create the file using this plugin, this file will look like this template file. In this template you can use the arguments defined in java.file-template. Following is an example template file
The parameter $name in the template file is read from the template settings file java.file-template.

You might have also observed other parameters as $date2, $author and $year. Where are they coming from? Well these are defined in the file ~/Library/Application Support/Sublime Text 2/Packages/FileTemplates/FileTemplates.sublime-settings. You can again add as much attributes as you need and use in your template file.

FileTemplates.sublime-settings








Saturday, April 14, 2018

Computation of Nth Fibonacci Number

Fibonacci Sequence

Fibonacci Sequence is the series of numbers which starts with two $1's$ in the beginning, then each number after that is the sum of two previous numbers in the sequence. So a fibonacci sequence is going to be:
1 1 2 3 5 8 13 21 34 .......

Computation of Nth Fibonacci Number

The definition of of Nth Fibonacci Number fib(n) is recursive in nature. i.e.
 
fib(n) = fib(n-2) + fib(n-1)
  
So the nth Fibonacci number can be easily computed using this recursive relation.

Problem

The problem with this solution is we are going to be computing same computation over and over again.
As you can see from the recursion tree, fib() method is called multiple times for the same value. The time complexity of this solution is going to be ${\cal O}(2^n)$ and the space complexity if ${\cal O}(1)$.

Memoization Solution

Since we are computing same computation over and over again, we could store our intermediate result and use it instead of computing again.

Complexity

Time complexity of this solution is ${\cal O}(n)$ and the Space Complexity is also ${\cal O}(n)$.

Dynamic Programming - Bottom Up Solution

Similar to Memoization, we can also solve it using Dynamic Programming - Bottom Up Approach.

Complexity

Time complexity of this solution is ${\cal O}(n)$ and the Space Complexity is also ${\cal O}(n)$.

Modified Dynamic Programming

We can see in the dynamic programming that to compute next fibonacci number we use only Two of the previous results. So we can infer that we don't need to store all previous results. Its enough to store only two previous results. Following is the solution using this principle.

Complexity

Time complexity of this solution is ${\cal O}(n)$ and the Space Complexity is ${\cal O}(1)$.






Tuesday, April 10, 2018

Kth Smallest Number in n x n Matrix

$\mathtt{REFERENCE}$ @ LeetCode

$\mathtt{RELATED\ PROBLEM\ -\ K\ Smallest\ Sum\ Pair}$

Task Description

Given an $n \times n$ integer Matrix sorted in non-decreasing order in row and column wise.

Find $kth$ smallest number in the matrix.

Solution 1 : Brute Force Solution

The naive solution would be to traverse through all the elements, sort them and find the $kth$ smallest item. There are $n^2$ elements in the matrix. Sorting them will take ${\cal O}(n^2log(n^2))$ time.

Solution 2: Efficient Solution

This Brute Force solution can be optimized by using Priority Queue. This solution is similar to the problem K Smallest Sum Pair.


    /**
    * Computes the Kth smallest item in the given row and column wise sorted 2D Matrix
    *
    */
    public int kthSmallest(int[][] matrix, int k) {
        PriorityQueue<int[]> smallestTracker = new PriorityQueue<int[]>(new Comparator<int[]>(){
            public int compare(int[] a, int[] b) {
                int x = matrix[a[0]][a[1]];
                int y = matrix[b[0]][b[1]];
                return x - y;
            }
        });
        
        for(int i = 0; i < matrix.length; i++) {
            smallestTracker.add(new int[]{i, 0});
        }
        
        int count = 0;
        int[] smallest = null;
        while (count < k) {
            smallest = smallestTracker.remove();
            if (smallest[1] < matrix.length - 1) {
                smallestTracker.add(new int[]{smallest[0], smallest[1] + 1});
            }
            count++;
        }
        return matrix[smallest[0]][smallest[1]];
    }

    

Time Complexity

Overall Time complexity is ${\cal O}(k log(n))$. The value $k$ can be $n^2$.
The space complexity is ${\cal O}(n)$ for the size of priority queue.






Monday, April 9, 2018

K Smallest Sum Pairs

$\mathtt{REFERENCE}$ @ LeetCode

$\mathtt{RELATED\ PROBLEM\ -\ Kth\ Smallest\ Numer\ in\ Sorted\ Matrix}$

Task Description

Given two integer arrays nums1 and nums1 sorted in non-decreasing order and an integer k.

Define a pair (u, v) consisting one element from the first array and one element from the second array.

Find k pairs with smallest sums.

Solution 1 : Brute Force Solution

The naive solution would be to find all possible pairs and find the best k pairs from it. If the two array contain n and m items, then there are nm possible pairs. Retrieving $k$ best pairs will take ${\cal \theta}(klog(mn))$ time.

Solution 2: Efficient Solution

This Brute Force solution can be optimized by using Priority Queue. The Priority Queue will hold sequence of number pairs (i, j) where $i$ is index in the first array and $j$ is that in the second array. Priority of the queue is determined by the sum of numbers at these indices.


  PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>(){
      @Override
      public int compare(int[] a, int[] b) {
          return nums1[a[0]] + nums2[a[1]] - nums1[b[0]] - nums2[b[1]];
      }
  });

    
Initially, for $i\ =\ 0$, all pairs with the second array is inserted into the priority queue. At this time, the first priority element is minimum element.

  for (int i = 0; i < nums2.length; i++) {
      queue.offer(new int[]{0, i});
  }

    
Then we keep on polling an element from the queue and insert into the result. For each poll, we will insert into the queue, $i + 1$ pairing with its corresponding unpaired index so far in the second array. This is repeated untill the queue is not empty or untill we have all the $k$ pairs required.

  while(!queue.isEmpty() && res.size() < k) {
      int[] item = queue.poll();
      res.add(new int[]{nums1[item[0]], nums2[item[1]]});
      
      if (item[0] == nums1.length - 1) {
          continue;
      } else {
          queue.offer(new int[]{item[0] + 1, item[1]});
      }
  }

    

Full Code


    public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        List<int[]> res = new ArrayList<int[]>();
        PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>(){
            @Override
            public int compare(int[] a, int[] b) {
                return nums1[a[0]] + nums2[a[1]] - nums1[b[0]] - nums2[b[1]];
            }
        });
        
        if(nums1.length == 0 || nums2.length == 0) {
            return res;
        }
        
        for (int i = 0; i < nums2.length; i++) {
            queue.offer(new int[]{0, i});
        }
        
        while(!queue.isEmpty() && res.size() < k) {
            int[] item = queue.poll();
            res.add(new int[]{nums1[item[0]], nums2[item[1]]});
            
            if (item[0] == nums1.length - 1) {
                continue;
            } else {
                queue.offer(new int[]{item[0] + 1, item[1]});
            }
        }
    
        return res;
    }

    

Time Complexity

Initial insertion into the priority queue takes ${\cal O}(m)$ time. During the iteration, for each minimum element polled from the queue, we insert at maximum only one element, hence the size of the queue is maintained ${\cal O}(m)$ and each iteration take ${\cal O}(log(m))$ time. The iteration is repeated untill we have all the $k$ results or the queue is empty. $\therefore$ Overall Time complexity is ${\cal O}(k log(m)) \approx {\cal O}(k log(n))$. The space complexity is ${\cal O}(n)$ for the size of priority queue.






Sunday, April 8, 2018

Number Pairs Whose Sum is Multiple of a Number X

$\mathtt{DOWNLOAD\ SOLUTION}$

Task Description

Kelly gives Ashley N chocolates each having a price pi, (where pi is the price of ith chocolate), and an integer X. She asks her to group the N chocolates in to pairs such that sum of prices of chocolates in each pair is a multiple of X.

Output yes if its possible to group the chocolates in to pairs and No if its not possible.

Solution 1: Considering all possible $nC2$ pairs

The first solution is to try to form pairs and satisfies our constraint. If at any point, if the constraint is not satisfied, we will need to Backtrack and try out different pairs.

For the size of array $n$, there are total of $nC2 \approx n^2$ possible combinations. So the complexity will be ${\cal O}(n^2)$.

Solution 2: Optimization of Solution 1

Consider four numbers $a,\ b,\ c,\ d$
Let,
            a + c is a multiple of X
       and, b + d is a multiple of X
    
So the numbers can be paired as $[a,\ c]$ and $[b,\ d]$

Now,what will happen if $a + b$ is also a multiple of X?

  a + c = CONST1 * X
  b + d = CONST2 * X
  a + b = CONST3 * X

  a + b + c + d = (CONST1 + CONST2) * X
  CONST3 * X + (c + d) = (CONST1 + CONST2) * X
  c + d = (CONST1 + CONST2 - CONST3) * X

This proves that (c + d) is also a multiple of X.

So in general, if
  • $a$ and $d$ pairs up,
  • $a$ pairs up with a set of numbers $S1$ and
  • $d$ pairs up with a set of numbers $S2$
Then, $a$ and $d$ can pair up with any number in the sets $S1$ and $S2$.

With this conclusion, we can optimise our Solution 1 by eliminating the Backtrack. We can keep on pairing up numbers. If all numbers have pairs, we can return True. If any number does not have a pair, we can return False.

Time Complexity

Even after the optimization, at worst case, for each element we need to go through all elements. $\therefore$ Total Time complexity is ${\cal O}(n^2)$. The space complexity is ${\cal O}(n)$ for the array paired.

Solution 3: Linear Time Solution

The problem can be solved in linear time by traversing the array only once.

Principle

If sum of two numbers a and b is multiple of a number X,

Then,
      (a % X) + (b % X) = X     if a % x > 0
                        = 0     if a % X == 0
    
So, in order for all numbers to pair up,
      number of elements in the array with modulo X value C  
          == number of elements in the array with module X value X - C
    
Following are the linear time solutions.

Solution Using Array

Solution Using Hash Map

Time Complexity

In this solution, we traverse through the input array only once. Important thing to note here is, the size of the array count is the value of input integer X. So if there is no constraint over the value of X, then the solution could be Pseudo-Polynomial. Otherwise , the overall time complexity is ${\cal O}(n)$. The Space complexity is ${\cal O}(X)$.






Wednesday, April 4, 2018

Maximum Profit from given array of Stock Prices - Programming Problem

$\mathtt{REFERENCE}$ @ Interve Cake

Problem Definition

You are given an array of Stock Prices. Index of the array represents the time corresponding to a price. Smaller index represents past time and larger index represents future time.

Now you need to write a method that takes the array as an input and returns the best profit that could be made by buying 1 stock and selling 1 stock.

Example


  int[] stockPrices = new int[] {15, 5, 10, 25, 55, 1};

  getMaxProfit(stockPrices); // returns 50 (buy at $5 and sell at $55)

    
Only the stock bought at past can be sold in the future. So the time difference must be at least 1 for conducting the transaction.

Brute Force Solution

Brute Force solution would be to consider every valid pair and keep updating the maximum profit that can be made.

  /**
   * Brute Force Approach to calculate the profit
   * @param stockPrices input stock prices
   * @return max profit
   */
  public static int getMaxProfit(int[] stockPrices) {
    int maxProfit = Integer.MIN_VALUE;

    for (int i = 0; i < stockPrices.length; i++) {
      for (int j = i+1; j < stockPrices.length; j++) {
        int profit = stockPrices[j] - stockPrices[i];
        if (profit > maxProfit) {
          maxProfit = profit;
        }
      }
    }

    return maxProfit;
  } // getMaxProfit

    

Time Complexity

The outer loop runs for all the prices i.e. $n$ times $n$ being the number of stock prices.

For the first outer loop, the inner loop runs for $n-1$ times
For the second outer loop, the inner loop runs for $n-2$ times
For the third outer loop, the inner loop runs for $n-3$ times and so on until 0.

So, the two loops run for $(n-1) + (n-2) + (n-3) + ...... + 2 + 1 + 0 \approx n^2$ times. Operations inside the loops are constant time operations.

$\therefore$ Total Time complexity is ${\cal O}(n^2)$. The space complexity is ${\cal O}(1)$.

Linear Time Solution

The problem can be solved in linear time by traversing the array only once. For each item traversed, we store the minimum value of the stock seen so far and update the maximum profit greedily.

  /**
   * Linear Time solution to find the max profit
   * @param stockPrices input stock prices
   * @return max profit
   */
  public static int getMaxProfit(int[] stockPrices) {
    int maxProfit = Integer.MIN_VALUE;
    int minPrice = stockPrices[0];

    for (int i = 1; i < stockPrices.length; i++) {
      int profit = stockPrices[i] - minPrice;
      if (maxProfit < profit) {
        maxProfit = profit;
      }

      if (minPrice > stockPrices[i]) {
        minPrice = stockPrices[i];
      }

    }
    return maxProfit;
  } // getMaxProfit

    

Time Complexity

In this solution, the stock prices are accessed only once. And for the stock price the processing is constant time.

$\therefore$ The overall time complexity is ${\cal O}(n)$. The Space complexity remains ${\cal O}(1)$.

Implementation








Building a Smart IDE: Identifying comments - HackerRank Problem

Difficulty: $\mathtt{Very\ Very\ Easy}$

Find the problem definition @ HackerRank

Solution

Simply travers thorugh each line and display the line when you know the line or part of it is comment

import java.io.*;
import java.util.*;

public class Solution {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        boolean comment = false;
        while(sc.hasNext()) {
            String line = sc.nextLine();
            
            if (line.trim().startsWith("/*")) comment = true;
            
            if (comment || line.trim().startsWith("//")) {
                System.out.println(line.trim());
            } else if (line.contains("//")) {
                int index = line.indexOf("//");
                System.out.println(line.substring(index));
            }
            
            if (line.endsWith("*/")) {
                comment = false;
            }
        }
    }
}

    

Time Complexity

The while loop in the code runs for $n$ number of times $n$ being the number of lines in the input. Time complexity of each loop depends upon the time taken by the methods like startsWith(), trim(), contains(), indexOf(), endsWith() and substring() of the String class.

Assuming all these methods are optimised to have the complexity ${\cal O})(n)$, $n$ being lenght of each line, overall complexity of the above solution is ${\cal O})(N)$, $N$ being total length of all lines.

Notes

Above solution doesn't considers special cases as:
  • Comments like /* Comment */ is nested inside a code.
  • String like // is a part of String constant in a code
  • String like /* */ is a part of String constant in a code







Tuesday, April 3, 2018

Electronics Shop - HackerRank Problem

Find the problem definition @ HackerRank

Brute-Force Solution

Using the Brute-Force method, this problem can be solved by considering every possible pairs. If the considered pair gives better result (i.e > max) and satisfies the constraints (i.e. <= s), then we select current pair as the solution. Result is returned after all the pairs have been considered.

  /**
   * Brute Force Solution
   * @param s
   * @param keyboards
   * @param drives
   * @return
   */
  public int getMoneySpent(int s, int[] keyboards, int[] drives) {
    int max = -1;
    for (int i = 0; i < keyboards.length; i++) {
      for (int j = 0; j < drives.length; j++) {
        int amount = keyboards[i] + drives[j];
        if (amount > max && amount <= s ) {
          if (max == s) return max;
          max = amount;
        }
      }
    }
    return max;
  }    
    

Time Complexity

Time Complexity of this solution depends upon the number of pairs considered. Since there are $n\ keyboards$ and $m\ drives$, total of $n \times m$ pairs are considered. Processing time for each pair, as we can see in the code, is constant time operation ${\cal O}(1)$. $\therefore$ The time complexity of this solution is ${\cal O}(n \times m)$. The space complexity is ${\cal O}(1)$ since we haven't use any extra data structure to hold inputs.

Better Solution

The problem could be optimized to solve in better time complexity. We can Sort one of the array and iterate through other array. While iterating through the other array, we apply the Binary Search on the sorted array to obtain the best pair. In order to keep the complexity low (Do the maths on your own ), I am going to sort the array with lower number of elements and iterate over the other one.

/**
   * Computes using Binary Search
   * @param keyboards
   * @param drives
   * @param s
   * @return
   */
  public int getMoneySpent(int[] keyboards, int[] drives, int s) {
    int max = -1;
    int[] larger = keyboards.length > drives.length ? keyboards : drives;
    int[] smaller = keyboards.length > drives.length ? drives : keyboards;

    Arrays.sort(smaller); // O(k logk)

    for (int i = 0; i < larger.length; i++) {  // O(n)
      if (larger[i] < s) {
        int pair = search(smaller, s - larger[i], 0, smaller.length); // O(logk)
        if (pair == -1) continue;
        if (max < smaller[pair] + larger[i]) {
          max = smaller[pair] + larger[i];
        }
      }
    }
    return max;
  } // getMoneySpent
  
  //----------------------------------------------------------------------------------

  /**
   * Searches the best pair using Binary Search
   * @param in
   * @param item
   * @param lo
   * @param hi
   * @return
   */
  public int search(int[] in, int item, int lo, int hi) {
    if (item < in[lo]) return -1;
    while (hi - lo > 1) {
      int midIdx = (lo + hi) / 2;
      if (item == in[midIdx]) return midIdx;
      else if (item > in[midIdx]) {
        lo = midIdx;
      } else {
        hi = midIdx;
      }
    }
    return lo;
  } // search

    

Time Complexity

Time Complexity of the solution depends upon the sorting of smaller array, iteration of larger array and the binary search on the sorted array.

Let, $n =$ Number of Elements in the larger array
       $k =$ Number of Elments in the smaller array

Then,
  1. Time Complexity of Sorting = ${\cal O})(k\ logk)$
  2. Time Complexity of iteration = ${\cal O}(n)$
  3. Time Complexity of Binary Serach = ${\cal O}(logk)$
$\therefore$ The overall Time Complexity is ${\cal O}(k\ logk + n\ logk) \approx {\cal O}(n\ logk)$. The Space Complexity is ${\cal O}(1)$