The post Multiply Two Big Integers appeared first on Algorithms and Problem Solving.

]]>Given two big integers represented as strings, Multiplication them and return the production as string.

For example, given a=2343324 and b=232232 then retiurn c = a*b = 23433242334323342 * 23223233232434324 = 544195652122144709711313995190808

We can see that the problem is trivial if we had given two small integers. But as the numbers can be really big we can’t fit the operands or the results into primitive data types. So, we need to go back to old school process where we do the multiplication of two numbers by multiplying one number with each digit of another and shift the subsequent results to left by 1 digit, and then add all these intermediate results for each digit of second number.

For example, let’s consider a = 231 and b = 51. Then the elementary process of multiplication would be –

231 51 ---------- 231 <--- 231 * 1 = 231 1155x <--- 231 * 5 = 1155, then shift left by 1 position is equivalent to padding one zero to right i.e. 11550 ----------- 11781 <--- adding 231+11550 = 11781

Basically, we need to take each digits from right to left of the second number and multiplying with the first number. For each digit in second number from right to left there will be one intermediate prod. We need to pad one additional zero to the end of subsequent intermediate results.

Now question is how to avoid overflow when multiplying first number with each of the digits of second number? For example, 23433242334323342 multiply by 4 certainly can't be done in integer or any other primitive type arithmetic. The solution is again in the old school way of multiplication. That means, from right to left, for each single digit in second number we multiply each single digit of first number and store the multiplication digit with extra digit storing as carry to be added in next digit multiply result.

Now we have a list of intermediate results that we need to add. Adding large numbers also suffers from overflow issue , so we also need to do this addition in old school way, i.e. add digit to digit at each position and push the carry forward.

The ld school algorithms are straightforward but the details is in the implementation. We need to make sure we construct, append zeros, and then store intermediate results efficiently so that we can do the final addition efficiently. Below is the implementation of the algorithm using stringbuffer construct. It runs in O(nm) where n=number of digits in first number and m=number of digits in second number.

//O(nm) public static String prod(String str1, String str2){ String res = new String("0"); int count = 0; for(int i = str2.length()-1; i>=0 ; i--){ int d2 = str2.charAt(i)-'0'; int carry = 0; StringBuffer prod = new StringBuffer(); for(int j = str1.length()-1; j>=0; j--){ int d1 = str1.charAt(j)-'0'; int p = carry+(d1*d2); prod.append(p%10); carry = p/10; } if(carry != 0){ prod.append(carry); } prod.reverse(); for(int k = 0; k<count; k++){ prod.append(0); } res = add(res, prod.toString()); count++; } return res.toString(); } //O(n); private static String add(String str1, String str2){ StringBuffer res = new StringBuffer(); int i = str1.length()-1; int j = str2.length()-1; int carry = 0; while(true){ if(i < 0 && j < 0){ break; } int d1 = i < 0 ? 0 : str1.charAt(i--)-'0'; int d2 = j < 0 ? 0 : str2.charAt(j--)-'0'; int sum = d1+d2+carry; res.append(sum%10); carry = sum/10; } if(carry != 0){ res.append(carry); } return res.reverse().toString(); }

The post Multiply Two Big Integers appeared first on Algorithms and Problem Solving.

]]>The post Patching Array appeared first on Algorithms and Problem Solving.

]]>Given a sorted positive integer array nums and an integer n, add/patch elements to the array such that any number in range [1, n] inclusive can be formed by the sum of some elements in the array. Return the minimum number of patches required.

This is a Leetcode problem.

Example 1:

nums = [1, 3], n = 6

Return 1.

Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4.

Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3].

Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6].

So we only need 1 patch.

Example 2:

nums = [1, 5, 10], n = 20

Return 2.

The two patches can be [2, 4].

Example 3:

nums = [1, 2, 2], n = 5

Return 0.

Note that, we should construct all numbers from 1 to n. A dirty take on this problem would be to to go from 1 to n and add all the numbers missing in the array. But certainly this is not the optimal solution. Because we don’t actually need all consecutive numbers to get another by adding them up. For example, A=[1,2,4]. In this case we don’t need 3 to make 3 because we can make 3 by adding 1 and 2. Also we don’t need 5 either. But if we want to make 8 then we have to add 8 in the list. Once we added 8 to the list i.e. A’=[1,2,4,8] then we don’t need to add any more element until 15 (why?).

Basically, as long as cumulative sum so far is greater than the number we need to create , we are good. But id cumsum falls below the current number (between 1 to n) we need to create , then we have to add the current cumsum to itself (why?). This is because we assumed at any particular time cumsum is equal or greater than the current element we need to create. That is we doubling the cumsum when we add a missing element.

Below is the implementation of the above idea in O(n) time and O(1) space.

public static int minPatches(int[] nums, int n) { int sum = 1; int i = 0; int count = 0; while(sum <= n){ if(i < nums.length && nums[i] <= sum){ sum+=nums[i++]; } else{ sum<<=1; count++; } } return count; }

The post Patching Array appeared first on Algorithms and Problem Solving.

]]>The post Min subarray (or sublist) to sort to make an unsorted array (or list) sorted appeared first on Algorithms and Problem Solving.

]]>Give a list of unsorted number, find the min window or min sublist or min subarray of the input, such as if sublist is sorted, the whole list is sorted too.

For example, given array a={1,2,3,5,4,4,3,3,7,8,9} then min subarray to sort the complete array sorted is {5,4,3,3}. More example : for a={1,2,3,5,6,4,2,3,3,7,8,9} then min subarray is {2,3,5,6,4,2,3,3}, for a={1,2,3,5,6,4,3,3,7,8,9,2} then min subarray is {2,3,5,6,4,2,3,3,7,8,9,2} etc.

Apparently the problems looks very complicated. But if we look into an example then we will see that it is rather one of simpler problems. Just believe in your intuition!

For example, a={1,2,3,5,4,4,3,3,7,8,9}. Note that 4 comes after 5 breaking the ascending sorting order. We understand the 5 and 4 must be contained in the resultant min subarray. Now believe in your intuition. How did you figure out that 5,4,3,3 is the answer? Because our brain affixed our attention to the two numbers : 5 and the right most 3. this is because these two numbers are related. How? Because 5 tells us the first number to be included in the min list. This also tells us that the left of 5 , i.e. 3 is the minimum number that may appear in the min list(why?).

We identified the start of the min list. But where does it end? As we know that 3 may be the minimum that ma appear in the list. This means the min list should contain all number greater than equal to 3 starting from 5. So, if we can identify somehow the max number that may appear in this min list then the minList ends at the position which has a higher value than the max number (why?).

What is the maximum number that can appear in the list? As we know 3 is the min then we can identify the right most 3 and get the maximum among elements between the left boundary i.e. 5 and rightmost min i.e. rightmost 3. The maximum tells us where is the rightmost boundary of the min array. The right boundary is the first number greater than the max on the right of the right most min. For example, in the current example it is 7. Then all numbers from 5 until 7 (excluding 7) constitute the resulting min subarray.

Below is the implementation of the above idea. The algorithm runs in O(n) time and O(1) space.

//O(n) time algorithm public static List<Integer> minListToBeSorted(int[] nums){ //find the first index from left to right where the sorted order disrupted //i.e. first index where next element is smaller int minIndex = -1; for(int i = 1; i< nums.length; i++){ if(nums[i] < nums[i-1]){ minIndex = i; break; } } //So, we got a potential mid element of the unsorted list //the minimum list must have a minimum element which is smaller or equal to this element for(int i = minIndex; i<nums.length; i++){ if(nums[i] < nums[minIndex]){ minIndex = i; } } //we can use the min element to identify the left boundary of the list because the left boundary //is the first element to the left greater than equal to this smallest element. //at the same time we can compute the maximum element in the left of this min element int l = minIndex; int r = minIndex; int maxLeft = nums[l]; while(l >= 0 && nums[l] >= nums[minIndex]){ maxLeft = Math.max(maxLeft, nums[l]); l--; } //we can use the max element to find the right most boundary of the min unsorted list by finding //first node in right of the smallest element that is greater than the max element while(r < nums.length && nums[r] <= maxLeft){ r++; } //all elments between List<Integer> res = new ArrayList<Integer>(); for(int i = l+1; l>=0 && r<=nums.length && i<r; i++){ res.add(nums[i]); } return res; }

The post Min subarray (or sublist) to sort to make an unsorted array (or list) sorted appeared first on Algorithms and Problem Solving.

]]>The post Find Next Greater Number Using Given Set Of Digits appeared first on Algorithms and Problem Solving.

]]>Given a set S of digits [0-9] and a number n. Find the smallest integer larger than n (ceiling) using only digits from the given set S. You can use a value as many times you want.

For example, d=[1, 2, 4, 8] and n=8753 then return 8811. For, d=[0, 1, 8, 3] and n=8821 then return 8830. For d=[0, 1, 8, 3] and n=8310 then return 8311.

As we know two numbers are equal when all their digits are same in respective positions. The smallest number greater than a number n must have at least one digit greater than its respective position and all the positions right to this position must contain the smallest digits possible.

For example, d=[0, 1, 8, 3] and n=8821 then as long as the digits match from MSB to LSB position we have the numbers matching. For example, [88]. If at a position we don’t find the digit in the given digit, for example 3 at position 2 of n, then we want to replace this with the next higher number from the digits d. The next higher digit in this case is 3. Once we find a higher digit we need to have the rest of the digits in the LSBs from this position as smallest as possible i.e. the smallest one. For example, in this case the rest of the position will be filled with smallest digit in d which is 0. So, final answer is 8830.

Question is how to get the next higher digit? We can simply sort the digit array and use binary search to get the floor (smallest number greater than or equal to key) from the array. However there is a special case when all the digits in the given number is contained in the digit. In this case we will end up in generating the input number itself as the next greater number (why?). How to solve this issue? If we do not find a higher digit in the whole scan then we need to replace the LSB of the number by the smallest digit that is strictly higher than the current digit at that position (why?).

The following is an O(nlgn) implementation of the above idea.

public static int[] nextHigherWithDigits(int[] digits, int n){ //get the target digits sorted int[] sortedDigits = Arrays.copyOf(digits, digits.length); Arrays.sort(sortedDigits); //get the digits of the number from LSB to MSB oder ArrayList<Integer> nums = new ArrayList<Integer>(); while(n>0){ nums.add(n%10); n/=10; } //reverse to get the digits in MSB to LSB order Collections.reverse(nums); boolean higherAdded = false; int[] res = new int[nums.size()]; int i = 0; //for each digit in thr number find the next higher in the sorted target digits for(int num : nums){ //if a higher digit was already found in previous step then rest of the digits should have the smallest digit if(higherAdded){ //add the smallest digit res[i++] = sortedDigits[0]; continue; } //otherwise , find the next higher (or equal) digit int nextHigher = binarySearchCeiling(sortedDigits, 0, sortedDigits.length-1, num); //if no such higher digit then no solution if(nextHigher == -1){ return null; } //otherwise if the digit is indeed higher then all subsequent digits should be smallest, so mark this event else if(sortedDigits[nextHigher] > num){ higherAdded = true; } //add the next higher (or equal digit) res[i++] = sortedDigits[nextHigher]; } //If we didn;t find any higher digit, which is only possible when we found all equal digits //then set the LSB to the next strictly higher number (not equal) if(!higherAdded){ int nextHigher = binarySearchCeiling(sortedDigits, 0, sortedDigits.length-1, res[i-1]+1); if(nextHigher == -1){ return null; } res[i-1] = sortedDigits[nextHigher]; } return res; }

public static int binarySearchCeiling(int A[], int l, int h, int key){ int mid = (l+h)/2; if(A[l] >= key){ return l; } if(A[h] < key ){ return -1; } if(A[mid] == key){ return mid; } //mid is greater than key, so either mid is the ceil or it exists in A[l..mid-1] else if(A[mid] > key){ if(mid-1 >= l && A[mid-1] <= key){ return mid; } else{ return binarySearchCeiling(A, l, mid-1, key); } } //mid is less than the key, so either mid+1 is the ceil or it exists in A[mid+1...h] else{ if(mid + 1 <= h && A[mid+1] >= key){ return mid+1; } else{ return binarySearchCeiling(A, mid+1, h, key); } } }

The post Find Next Greater Number Using Given Set Of Digits appeared first on Algorithms and Problem Solving.

]]>The post Vertical and Zigzag Traversal of Binary Tree appeared first on Algorithms and Problem Solving.

]]>Given a binary tree. Print the nodes in vertical and zigzag manner.

For example, we have binary tree below:

1 / \ 2 3 / \ / \ 4 5 6 7

vertical traversal will output:

4

2

1 5 6

3

7

We can clearly see that we are printing the nodes in vertical order such that a vertical line is scanning from left most node to right most node and printing all the nodes on the same vertical in a single line. How do we do it? Note that, the left most node will be printed first then its root then it’s right node. So, basically we are giving highest priority to left subtree, then root, and then lowest priority to right subtree. This gives us enough hint to solve this problem. How?

We will basically traverse the tree in pre-order (root -> left -> right) such a way that we assign one higher priority when we go left and one lower priority when we go right. Then we will basically put all the nodes with same priority value in a map. Once the traversal is done we can print the map nodes in the order of priority, sam priority nodes in the same line. For example, the following tree shows the assigned priority for each node in vertical traverse order [lower value means higher priority].

1,0 / \ 2,-1 3,1 / \ / \ 4,-2 5,0 6,0 7,2 map : -2 -> {4} -1 -> {2} 0 -> {1, 5, 6} 1 -> {3} 2 -> {7}

Below is a simple implementation of this idea.

public static void verticalTrversal(BTNode root){ int[] minmax = new int[]{Integer.MAX_VALUE, Integer.MIN_VALUE}; Map<Integer, ArrayList<BTNode>> verticals = new HashMap<Integer, ArrayList<BTNode>>(); traverse(root, verticals, 0, minmax); for(int i = minmax[0]; i<=minmax[1]; i++){ if(verticals.containsKey(i)){ for(BTNode vnode : verticals.get(i)){ System.out.print(vnode.key+","); } System.out.println(); } } } private static void traverse(BTNode node, Map<Integer, ArrayList<BTNode>> verticals, int score, int[] minmax){ if(!verticals.containsKey(score)){ verticals.put(score, new ArrayList<BTNode>()); } verticals.get(score).add(node); minmax[0] = Math.min(minmax[0], score); minmax[1] = Math.max(minmax[1], score); if(node.left != null){ traverse(node.left, verticals, score-1, minmax); } if(node.right != null){ traverse(node.right, verticals, score+1, minmax); } }

**ZigZag Traversal**

Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).

For example: Given binary tree

3 / \ 9 20 / \ 15 7

print its zigzag level order traversal as:

3

20,9

15,7

If we look closely then we can notice that this is basically a level order (or horizontal) traversal where we are changing direction (left or right) at alternate level. Please read my previous post on level order traversal before reading more in this article.

So, basically we will do a level order (left to right per level) traversal but we need to print in reverse order in alternate level. We can keep a stack to save the nodes in reverse order (right to left) if we are in a even level. At the end of an even level we will print from the stack. On the other hand for odd level we just print as we traverse from left to right. Below is the implementation of this level order traversal using a queue.

public static void zigzagTraversal(BTNode root){ Queue<BTNode> queue = new ArrayDeque<BTNode>(); queue.offer(root); BTNode node = null; int count = 1; int level = 0; Stack<BTNode> reverse = new Stack<BTNode>(); while(!queue.isEmpty()){ node = queue.poll(); count--; //right to left if((level&1) == 0){ reverse.push(node); } else{ System.out.print(node.key); } if(node.left != null){ queue.offer(node.left); } if(node.right != null){ queue.offer(node.right); } //level ended if(count == 0){ if((level&1) == 0){ while(!reverse.isEmpty()){ System.out.print(reverse.pop().key); } } System.out.println(); count = queue.size(); level++; } } }

The post Vertical and Zigzag Traversal of Binary Tree appeared first on Algorithms and Problem Solving.

]]>The post Find k such that kth row is all zero and kth col is all one in a matrix appeared first on Algorithms and Problem Solving.

]]>Given a Boolean Matrix, find k such that all elements in k’th row are 0 and k’th column are 1. Do it in O(n) time

Given a binary matrix mat[n][n], find k such that all elements in k’th row are 0 and all elements in k’th column are 1. The value of mat[k][k] can be anything (either 0 or 1). If no such k exists, return -1.

Examples:

Input: mat[n][n] = {{0, 1, 1, 0, 1},

{0, 0, 0, 0, 0},

{1, 1, 1, 0, 0},

{1, 1, 1, 1, 0},

{1, 1, 1, 1, 1}};

Output: 1

All elements in 1’st row are 0 and all elements in

1’st column are 1. mat[1][1] is 0 (can be any value)

Input: mat[n][n] = {{0, 1, 1, 0, 1},

{0, 0, 0, 0, 0},

{1, 1, 1, 0, 0},

{1, 0, 1, 1, 0},

{1, 1, 1, 1, 1}};

Output: -1

There is no k such that k’th row elements are 0 and

k’th column elements are 1.

A trivial solution would be to find all rows that has sum at most 1 and then check corresponding columns to check if column has sum at least 4 (why?). This is a O(n^2) solution however. How can we do it in O(n)?

Carefully looking into the examples we can see there can be at most one solution of this problem because if we have more than one solution then we have more than one row that satisfies the constraint which automatically tells us that more than one columns in the row has 1, which in turn contradicts the row condition. So, we there is at most one such k.

Now, as there is at most one such k then the candidate row, column is crossing at (k,k) where the value can be either 0 or 1 and all other values in the row are 0 , and all other values in the column are 1. How to find such a intersecting point?

We can actually start from a corner, let’s say the top-left. If this corner contains a 0 then we try to validate if this row can be a candidate. If all other values int the row are zero then it is a candidate row and we need to check for column condition. Otherwise, if there is a one value in the row then this row can’t be the solution and we go to next row.

On the other hand if the corner was a 1 then we have to check the validity of the column. If all other column values are 1 then this is a candidate column and we need to validate the row constraint. Otherwise, if there was a zero in the column then this column can’t be the candidate and we go to next column.

Each time, we are either incrementing a row or a column. So, will visit at most visit 2n numbers of element in this way and hence the time complexity is O(n). Below is the implementation of this idea.

public static int findKthRowCol(int mat[][]){ int n = mat.length; int m = mat[0].length; int i = 0; int j = 0; int candidate = -1; while(i < n && j < m){ //check the row for all zero if(mat[i][j] == 0){ int k = j+1; while(k < m && mat[i][k] == 0){ k++; } if(k == m){ candidate = i; break; } //if not all zero in this row, then this row can't be the candidate else{ i++; } } //check the column for all ones else{ int k = i+1; while(k < n && mat[k][j] == 0){ k++; } if(k == n){ candidate = i; break; } //if not all are 1 then this col can't be the candidate else{ j++; } } } //we found a row/cold candidate, validate the rowand columnd if(candidate != -1){ for(j = 0; j<n; j++){ if(j != candidate && mat[candidate][j] != 0){ return -1; } } for(i = 0; i<n; i++){ if(i != candidate && mat[i][candidate] != 1){ return -1; } } return candidate; } return candidate; }

The post Find k such that kth row is all zero and kth col is all one in a matrix appeared first on Algorithms and Problem Solving.

]]>The post Permuting Lists of Lists – Print all possible words from phone digits appeared first on Algorithms and Problem Solving.

]]>Given a list of arraylists containing elements, write a function that prints out the permutations of of the elements such that, each of the permutation set contains only 1 element from each arraylist and there are no duplicates in the list of permutation sets.

For example: consider the following lists

L1= {a1,b1,c1,d1} L2= {a2,b2,c2} L3= {a3, b3, c3} Valid Permutations are: {a1, a2, a3} {a1, a2, b3} {a1, a2, c3} {a1, b2, a3} {a1, b2, b3} {a1, b2, c3} ... ... ... {d1, c2, a3} {d1, c2, b3} {d1, c2, c3} Please note that {a1,b2,c3} is same set as {b2,a1,c3}

We can solve this problem similar to we did solve the combination problem in a previous post here. This problem can be solved similarly where we consider the the input list as a multidimensional string that contains a list of string at each position. Anytime we will consider one single item. So, for each string in first list we do recurse to all other lists to find the combinations. We print the result whenever we reach the last list and output contains one elements from each of the n lists. Below is the implementation of this idea.

public static void permuteList(String[][] list, int start, ArrayList<String> perms){ if(start == list.length){ if(perms.size() == list.length) System.out.println(perms.toString()); return; } for(int i = 0; i < list[start].length; i++){ perms.add(list[start][i]); for(int j = start+1; j <= list.length; j++){ permuteList(list, j, perms); } perms.remove(list[start][i]); } }

**Print All Words Based On Phone Number**

Now let’s consider this problem,

Given a keypad as shown in diagram, and a n digit number, list all words which are possible by pressing these numbers.

For example if input number is 234, possible words which can be formed are (Alphabetical order):

adg adh adi aeg aeh aei afg afh afi bdg bdh bdi beg beh bei bfg bfh bfi cdg cdh cdi ceg ceh cei cfg cfh cfi.

How do we solve this problem? Let’s quickly take our phone and look into the keypad. We will find –

0 --> {} 1 --> {} 2 --> {a,b,c} 3 --> {d,e,f} 4 --> {g,h,i} 5 --> {j,k,l} 6 --> {m,n,o} 7 --> {p,q,r,s} 8 --> {t,u,v} 9 --> {w,x,y,z}

now if we press 2 there could be 3 possible values {a,b,c}. Then if we press 3 then the possible words would be all combination of 2 letters, one from 2–>{a,b,c} and other from 3->{d,e,f}. If we press down another number then the words formed will have first letter from 2-{a,b,c}, second number from 3->{d,e,f}, and 3rd letter from 4->{g,h,i}. Does this look familiar? Yes, we just solved the problem in the beginning of the article, this is basically permutation of lists of list.

Basically we run the algorithm with a list {L2, L3,L4} where

L2= {a,b,c}

L3= {d,e,f}

L4= {g,h,i}

So, given a sequence of n digits we will generate a list of lists using a precomputed map from digit to list of characters. Then we will call the permuteList.

The post Permuting Lists of Lists – Print all possible words from phone digits appeared first on Algorithms and Problem Solving.

]]>The post Power Set or Super Set of a Set appeared first on Algorithms and Problem Solving.

]]>Given a set of characters. Find the power set or super set of the set.

For example, S={a,b,c}, then powerSet = {{}, {a}, {b}, {c}, {a,b}, {b,c}, {a,c}, {a,b,c}}.

For a set of n elements there are 2^n elements on the super set including the empty set. The brute-force method would be to find all possible combinations of the elements using 0, 1, 2,…n elements. But that will have an exponential time al? complexity. How can we do it in less than exponential?

Notice that, if we represent each unique letters by a bit position in a n bit integer than the power set will look like, for example for n=3,

{} -> 000 {a} -> 001 {b} -> 010 {c} -> 100 {a, b} -> 011 {b, c} -> 110 {a, c} -> 101 {a,b,c}-> 111

That is we can generate the power set of n numbers by looking at the bit positions n bit integers. So, we will basically take each integer from 0 to 2^n-1 and for each we will check the bit positions set. Each number corresponds to a set in the superset and each set bit position will contribute to an element in the set. Below is the implementation of this idea which runs in O(n*2^n) time and O(1) space.

public static List<List<Character>> powerSet(char[] chars){ int n = chars.length; List<List<Character>> powerSet = new ArrayList<List<Character>>(); //superSet.add(Collections.emptyList()); if(n == 0){ return powerSet; } int max = (int)Math.pow(2, n); for(int i = 0; i<max; i++){ List<Character> set = new ArrayList<Character>(); for(int j = 0; j<n; j++){ if((i & (1<<j)) > 0){ set.add(chars[j]); } } powerSet.add(set); } return powerSet; }

The post Power Set or Super Set of a Set appeared first on Algorithms and Problem Solving.

]]>The post Min Sum Path in a Triangle appeared first on Algorithms and Problem Solving.

]]>Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

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

The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

But for the following triangle –

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

The minimum path sum from top to bottom is 11 (i.e., 2 + 5 + 5 + 1 = 13).

The problem somewhat resemble a tree structure and hence finding minimum sum path from root to a leaf. But if we look carefully then we will notice that this is a simple dynamic programming problem as the problem is well defined. At each level we need to choose the node that yields a min total sum with the following relation –

dp[level][i] = triangle[level][i] + min{dp[next_level][i], dp[next_level][i+1]}

Notice that if we start from top and do a topdown dp then we might get wrong result as in example 2 it will return 15 = [2, 4, 5, 4]. But the actual minimum path is 13 = [2, 5, 5, 1]. That is we need to do a bottom-up computation for the dp. That is,

dp[level][i] = triangle[level][i] + min{dp[level+1][i], dp[level+1][i+1]}

Below is the implementation of this approach that runs in O(n^2) time and takes O(n^2) space.

//O(n^2) time and O(n^2) space for dp table public static int triangleMinSumPath(List<int[]> triangle){ int levels = triangle.size(); int dp[][] = new int[levels][levels]; dp[levels-1] = triangle.get(levels-1); //bottom up Dijkstra for(int l = levels-2; l>=0 ; l--){ for(int i = 0; i<=l; i++){ dp[l][i] = Math.min(dp[l+1][i], dp[l+1][i+1]) + triangle.get(l)[i]; } } return dp[0][0]; }

**O(n) space solution**

If we print the dp table of the above code for example 2 then we will see the following –

Triangle - [2], [5,4], [5,5,7], [1,4,8,3] dp table - 13, 0, 0, 0 11, 13, 0, 0 6, 9, 10, 0 1, 4, 8, 3

If we look closely then we can see that the table has meaningful values in lower half only and at each level bottom up we have one of the column value getting fixed. So, we could have basically used the bottom level array as the dp table and at each level we update the columns bottom up. In this way we can decrease the space from O(n^2) to O(n). Below is the modified implementation of the above code by using O(n) space for dp table.

//O(n^2) time and O(n) space public static int triangleMinSumPath2(List<int[]> triangle){ int levels = triangle.size(); int dp[] = new int[levels]; dp = triangle.get(levels-1); //bottom up Dijkstra for(int l = levels-2; l>=0 ; l--){ for(int i = 0; i<=l; i++){ dp[i] = Math.min(dp[i], dp[i+1]) + triangle.get(l)[i]; } } return dp[0]; }

The post Min Sum Path in a Triangle appeared first on Algorithms and Problem Solving.

]]>The post pow(x, y) in O(lgn) appeared first on Algorithms and Problem Solving.

]]>Implement pow(x,y) in logarithm time

The problem would be straightforward if we are allowed to do it in O(n) time as we can simply multiple x by itself y times. But how to do it in log time?

The problem description itself is telling us how to implement it in log time. If we need to find power of x raised to y in logarithmic time then somehow we need to make the computation tree into half in each iteration. For example, a^5 = a^2*a^2*a. a^10 = a^5*a^5. So, basically if we can compute a^(y/2) once then we use this computation to find a^y by simply multiplying the result to itself if y is even. If y is odd then we need to multiply x once more with the even multiplication result. Below is the implementation of this idea in both recursive and iterative approach. Both code runs in O(lgn) time (why?).

//O(lgn) public static int powRec(int x, int y){ if(y == 0){ return 1; } if(y == 1){ return x; } int pow = powRec(x, y/2); if((y&1) != 0){ return pow*pow*x; } else{ return pow*pow; } } //O(lgn) public static int powIter(int x, int y){ int pow = 1; if(y == 0){ return 1; } if(y == 1){ return x; } while(y > 0){ //if y is odd if((y&1) != 0){ pow*=x; } //divide by 2 y >>= 1; //calclate x^2 x = x*x; } return pow; }

The post pow(x, y) in O(lgn) appeared first on Algorithms and Problem Solving.

]]>