Você está na página 1de 185

Find the smallest window in a string containing all characters of another string

Given two strings string1 and string2, find the smallest substring in string1 containing all characters of string2 efficiently. For Example: Input string1: this is a test string Input string2: tist Output string: t stri Method 1 (Brute force solution) a) Generate all substrings of string1 (this is a test string) b) For each substring, check whether the substring contains all characters of string2 (tist) c) Finally print the smallest substring containing all characters of string2. Method 2 (Efficient Solution) 1) Build a boolean count array count[] of string 2 count['i'] = 1 count['t'] = 2 count['s'] = 1 2) Scan the string1 from left to right until we find all the characters of string2. To check if all the characters are there, use count[] built in step 1. So we have substring this is a t containing all characters of string2. Note that the first and last characters of the substring must be present in string2. Store the length of this substring as min_len. 3) Now move forward in string1 and keep adding characters to the substring this is a t. Whenever a character is added, check if the added character matches the left most character of substring. If matches, then add the new character to the right side of substring and remove the leftmost character and all other extra characters after left most character. After removing the extra characters, get the length of this substring and compare with min_len and update min_len accordingly. Basically we add e to the substring this is a t, then add s and thent. t matches the left most character, so remove t and h from the left side of the substring. So our current substring becomes is a test. Compare length of it with min_len and update min_len. Again add characters to current substring is a test. So our string becomes is a test str. When we add i, we remove leftmost extra characters, so current substring becomes t stri. Again, compare length of it with min_len and update min_len. Finally add n and g. Adding these characters doesnt decrease min_len, so the smallest window remains t stri. 4) Return min_len.

Given a set T of characters and a string S, find the minimum window in S which will contain all the characters in T in complexity O(n). eg, S = ADOBECODEBANC T = ABC Minimum window is BANC.
The best solution, is in fact simpler. This best approach is suggested by someone who goes by the id stormrage in the MITBBS forum. Notice how complicated the above solution is. It uses a hash table, a queue, and a sorted map. During an interview, the problems tend to be short and the solution usually can be coded in about 50 lines of code. So be sure that you say out loud what you are thinking and keep communication opened with the interviewer. Check if your approach is unnecessary complex, he/she might be able to give you guidance. The last thing you want to do is to get stuck in a corner and keep silent. To help illustrate this approach, I use a different example: S = acbbaca and T = aba. The idea is mainly based on the help of two pointers (begin and end position of the window) and two tables (needToFind and hasFound) while traversing S. needToFind stores the total count of a character in T and hasFound stores the total count of a character met so far. We also use a count variable to store the total characters in T thats met so far (not counting characters where hasFound[x] exceeds needToFind[x]). When count equals Ts length, we know a valid window is found. Each time we advance the end pointer (pointing to an element x), we increment hasFound[x] by one. We also increment count by one if hasFound[x] is less than or equal to needToFind[x]. Why? When the constraint is met (that is, count equals to Ts size), we immediately advance begin pointer as far right as possible while maintaining the constraint. How do we check if it is maintaining the constraint? Assume that begin points to an element x, we check if hasFound[x] is greater than needToFind[x]. If it is, we can decrement hasFound[x] by one and advancing begin pointer without breaking the constraint. On the other hand, if it is not, we stop immediately as advancing begin pointer breaks the window constraint.

Finally, we check if the minimum window length is less than the current minimum. Update the current minimum if a new minimum is found. Essentially, the algorithm finds the first window that satisfies the constraint, then continue maintaining the constraint throughout.

i) S = acbbaca and T = aba.

ii) The first minimum window is found. Notice that we cannot advance begin pointer as hasFound['a'] == needToFind['a'] == 2. Advancing would mean breaking the constraint.

iii) The second window is found. begin pointer still points to the first element a. hasFound['a'] (3) is greater than needToFind['a'] (2). We decrement hasFound['a'] by one and advance begin pointer to the right.

iv) We skip c since it is not found in T. Begin pointer now points to b. hasFound['b'] (2) is greater than needToFind['b'] (1). We decrement hasFound['b'] by one and advance begin pointer to the right.

v) Begin pointer now points to the next b. hasFound['b'] (1) is equal to needToFind['b'] (1). We stop immediately and this is our newly found minimum window.

Both the begin and end pointers can advance at most N steps (where N is Ss size) in the worst case, adding to a total of 2N times. Therefore, the run time complexity must be in O(N). ? 1 2 3 4
// Returns false if no valid window is // true and updates minWindowBegin and // starting and ending position of the bool minWindow(const char* S, const char int &minWindowBegin, int found. Else returns minWindowEnd with the minimum window. *T, &minWindowEnd) {

5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 } 4 2 5 2 6 2 7 2 8 2 9 3

int sLen = strlen(S); int tLen = strlen(T); int needToFind[256] = {0}; for (int i = 0; i < tLen; i++) needToFind[T[i]]++; int hasFound[256] = {0}; int minWindowLen = INT_MAX; int count = 0; for (int begin = 0, end = 0; end < sLen; end++) { // skip characters not in T if (needToFind[S[end]] == 0) continue; hasFound[S[end]]++; if (hasFound[S[end]] <= needToFind[S[end]]) count++; // if window constraint is satisfied if (count == tLen) { // advance begin index as far right as possible, // stop when advancing breaks window constraint. while (needToFind[S[begin]] == 0 || hasFound[S[begin]] > needToFind[S[begin]]) { if (hasFound[S[begin]] > needToFind[S[begin]]) hasFound[S[begin]]--; begin++; } // update minWindow if a minimum length is met int windowLen = end - begin + 1; if (windowLen < minWindowLen) { minWindowBegin = begin; minWindowEnd = end; minWindowLen = windowLen; } // end if } // end if } // end for return (count == tLen) ? true : false;

0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5

Get Level of a node in a Binary Tree


Given a Binary Tree and a key, write a function that returns level of the key. For example, consider the following tree. If the input key is 3, then your function should return 1. If the input key is 4, then your function should return 3. And for key which is not present in key, then your function should return 0.

The idea is to start from the root and level as 1. If the key matches with roots data, return level. Else recursively call for left and right subtrees with level as level + 1.
/* A tree node structure */ class node{ int data; node left; node right; }; /*Helper function for getLevel(). It returns level of the data if data is present in tree, otherwise returns 0.*/ int getLevelUtil(node node, int data, int level) { if ( node == null ) return 0; if ( node.data == data ) return level; return getLevelUtil ( node.left, data, level+1) | getLevelUtil ( node.right, data, level+1);

Output:Level of 3 is 1;Level of 6 is 0. Time Complexity: O(n) where n= number of Nodes.

Sorted insert for circular linked list


Write a C function to insert a new value in a sorted Circular Linked List (CLL). For example, if the input CLL is following.

Algorithm: Allocate memory for the newly inserted node and put data in the newly allocated node.

Let the pointer to the new node be new_node. After memory allocation, following are the three cases that need to be handled.
1) Linked List is empty: a) since new_node is the only node in CLL, make a self loop. new_node->next = new_node; b) change the head pointer to point to new node. *head_ref = new_node; 2) New node is to be inserted just before the head node: (a) Find out the last node using a loop. while(current->next != *head_ref) current = current->next; (b) Change the next of last node. current->next = new_node; (c) Change next of new node to point to head. new_node->next = *head_ref; (d) change the head pointer to point to new node. *head_ref = new_node; 3) New node is to be inserted somewhere after the head: (a) Locate the node after which new node is to be inserted. while ( current->next!= *head_ref && current->next->data < new_node->data) { current = current->next; } (b) Make next of new_node as next of the located pointer new_node->next = current->next; (c) Change the next of the located pointer current->next = new_node; /* structure for a node */ class node{ int data; node next; }; /* function to insert a new_node in a list in sorted way. Note that this function expects a pointer to head node as this can modify the head of the input linked list */ void sortedInsert(node head_ref,node new_node) { node current = head_ref; // Case 1 of the above algo if (current == null){ new_node.next = new_node; head_ref = new_node; } // Case 2 of the above algo else if (current.data >= new_node.data) { /* If value is smaller than head's value then we need to change next of last node */

while(current.next != head_ref) current = current.next; current.next = new_node; new_node.next = head_ref; head_ref = new_node;

// Case 3 of the above algo else { /* Locate the node before the point of insertion */ while (current.next!= head_ref && current.next.data < new_node.data) current = current.next; new_node.next = current.next; current.next = new_node;

} }

Time Complexity: O(n) where n is the number of nodes in the given linked list. Case 2 of the above algorithm/code can be optimized. To implement the suggested change we need to modify the case 2 to following.
// Case 2 of the above algo else if (current.data >= new_node.data) { // swap the data part of head node and new node swap(current.data,new_node.data); // assuming that we have a function swap(int *, int *) new_node.next = head_ref.next; head_ref.next = new_node; }

Calculate Logn in one line


Write a one line C function that calculates and returns . For example, if n = 64, then your function should return 6, and if n = 129, then your function should return 7. Following is a solution using recursion.
int Log2n(int n){ return (n > 1)? 1 + Log2n(n/2): 0; }

Let us try an extended verision of the problem. Write a one line function Logn(n ,r) which returns . Following is the solution for the extended problem.
int Logn(int n, int r){

return (n > r-1)? 1 + Logn(n/r, r): 0;

Find k-th smallest element in BST (Order Statistics in BST)


Given root of binary search tree and K as input, find K-th smallest element in BST. For example, in the following BST, if k = 3, then output should be 10, and if k = 5, then output should be 14.

Method 1: Using Inorder Traversal. Inorder traversal of BST retrieves elements of tree in the sorted order. The inorder traversal uses stack to store to be explored nodes of tree (threaded tree avoids stack and recursion for traversal, see this post). The idea is to keep track of popped elements which participate in the order statics. Hypothetical algorithm is provided below.Time complexity: O(n) where n is total nodes in tree.. Algorithm:
/* initialization */ node pCrawl = root; Stack<node> stack=new Stack<node>(); /*set initial stack element as NULL (sentinal)*/ /* traverse upto left extreme */ while(pCrawl!=null){ stack.push(pCrawl); pCrawl = pCrawl.left; } /* process other nodes */ while( (pCrawl = stack.pop())!=null){ /*stop if sufficient number of elements are popped.*/ if( pCrawl.right!=null) pCrawl = pCrawl.right; while( pCrawl!=null){ stack.push(pCrawl); pCrawl = pCrawl.left; } }

#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0]) /* just add elements to test */ /* NOTE: A sorted array results in skewed tree */ int ele[] = { 20, 8, 22, 4, 12, 10, 14 }; /* same alias */ typedef struct node_t node_t; /* Binary tree node */ struct node_t { int data; node_t* left; node_t* right; }; node_t *k_smallest_element_inorder(stack_t *stack, node_t *root, int k) { stack_t *st = stack; node_t *pCrawl = root; /* move to left extremen (minimum) */ while( pCrawl ) { push(st, pCrawl); pCrawl = pCrawl->left; } /* pop off stack and process each node */ while( pCrawl = pop(st) ) { /* each pop operation emits one element in the order */ if( !--k ) { /* loop testing */ st->stackIndex = 0; break; } /* there is right subtree */ if( pCrawl->right ) { /* push the left subtree of right subtree */ pCrawl = pCrawl->right; while( pCrawl ) { push(st, pCrawl); pCrawl = pCrawl->left;

} /* pop off stack and repeat */ } }

/* node having k-th element or NULL node */ return pCrawl; }

Method 2: Augmented Tree Data Structure. The idea is to maintain rank of each node. We can keep track of elements in a subtree of any node while building the tree. Since we need K-th smallest element, we can maintain number of elements of left subtree in every node. Assume that the root is having N nodes in its left subtree. If K = N + 1, root is K-th node. If K < N, we will continue our search (recursion) for the Kth smallest element in the left subtree of root. If K > N + 1, we continue our search in the right subtree for the (K N 1)-th smallest element. Note that we need the count of elements in left subtree only. Time complexity: O(n) where n is total nodes in tree.
start: if K = root.leftElement + 1 root node is the K th node. goto stop else if K > root.leftElements K = K - (root.leftElements + 1) root = root.right goto start else root = root.left goto srart stop:

Program for Fibonacci numbers


The Fibonacci numbers are the numbers in the following integer sequence.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 141, .. In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation

Write a function int fib(int n) that returns curl error: couldn't connect to host. For example, if n = 0, then fib() should return 0. If n = 1, then it should return 1. For n > 1, it should return Following are different methods to get the nth Fibonacci number. Method 1 ( Use recursion ) A simple method that is a direct recusrive implementation mathematical recurance relation given above.
int fib(int n) { if ( n <= 1 ) return n; return fib(n-1) + fib(n-2); }

Time Complexity: T(n) = T(n-1) + T(n-2) which is exponential. We can observe that this implementation does a lot of repeated work (see the following recursion tree). So this is a bad implementation for nth Fibonacci number.
\ fib(4) fib(3) / \ / \ fib(3) fib(2) fib(2) fib(1) / \ / \ / \ fib(2) fib(1) fib(1) fib(0) fib(1) fib(0) / \ fib(1) fib(0) / fib(5)

Extra Space: O(n) if we consider the fuinction call stack size, otherwise O(1). Method 2 ( Use Dynamic Programming ) We can avoid the repeated work done is the method 1 by storing the Fibonacci numbers calculated so far.
int fib(int n) { /* Declare an array to store fibonacci numbers. */ int[] f=new int[n+1]; int i;

/* 0th and 1st number of the series are 0 and 1*/ f[0] = 0; f[1] = 1; for (i = 2; i <= n; i++){ /* Add the previous 2 numbers in the series and store it */ f[i] = f[i-1] + f[i-2]; } return f[n];

Time Complexity: O(n) Extra Space: O(n) Method 3 ( Space Otimized Method 2 ) We can optimize the space used in method 2 by storing the previous two numbers only because that is all we need to get the next Fibannaci number in series.
int fib(int n) { int a = 0, b = 1, c, i; if( n == 0) return a; for (i = 2; i <= n; i++) { c = a + b; a = b; b = c; } return b; }

Time Complexity: O(n) Extra Space: O(1) Method 4 ( Using power of the matrix {{1,0},{0,1}} ) This another O(n) which relies on the fact that if we n times multiply the matrix M = {{1,0},{0,1}} to itself (in other words calculate power(M, n )), then we get the (n+1)th Fibonacci number as the element at 0,0 in the resultant matrix. The matrix representation gives the following closed expression for the Fibonacci numbers:

/* Helper function that multiplies 2 matricies F and M of size 2*2, and puts the multiplication result back to F[][] */ void multiply(int F[2][2], int M[2][2]);

/* Helper function that calculates F[][] raise to the power n and puts the result in F[][].Note that this function is desinged only for fib() and won't work as general power function */ void power(int F[2][2], int n); int fib(int n) { int F[2][2] = {{1,1},{1,0}}; if(n == 0) return 0; power(F, n-1); return F[0][0];

void multiply(int F[2][2], { int x = F[0][0]*M[0][0] int y = F[0][0]*M[0][1] int z = F[1][0]*M[0][0] int w = F[1][0]*M[0][1] F[0][0] F[0][1] F[1][0] F[1][1] } = = = = x; y; z; w;

int M[2][2]) + + + + F[0][1]*M[1][0]; F[0][1]*M[1][1]; F[1][1]*M[1][0]; F[1][1]*M[1][1];

void power(int F[2][2], int n) { int i; int M[2][2] = {{1,1},{1,0}}; // n - 1 times multiply the matrix to {{1,0},{0,1}} for ( i = 2; i <= n; i++ ) multiply(F, M); }

Time Complexity: O(n) Extra Space: O(1)

Method 5 ( Optimized Method 4 ) The method 4 can be optimized to work in O(Logn) time complexity. We can do recursive multiplication to get power(M, n) in the prevous method .
void multiply(int F[2][2], int M[2][2]); void power(int F[2][2], int n); /* function that returns nth Fibonacci number */ int fib(int n) { int F[2][2] = {{1,1},{1,0}}; if(n == 0) return 0; power(F, n-1); return F[0][0]; } /* Optimized version of power() in method 4 */ void power(int F[2][2], int n) { if( n == 0 || n == 1) return; int M[2][2] = {{1,1},{1,0}}; power(F, n/2); multiply(F, F); if( n%2 != 0 ) multiply(F, M);

void multiply(int F[2][2], { int x = F[0][0]*M[0][0] int y = F[0][0]*M[0][1] int z = F[1][0]*M[0][0] int w = F[1][0]*M[0][1] F[0][0] F[0][1] F[1][0] F[1][1] = = = = x; y; z; w;

int M[2][2]) + + + + F[0][1]*M[1][0]; F[0][1]*M[1][1]; F[1][1]*M[1][0]; F[1][1]*M[1][1];

} Time Complexity: O(Logn) Extra Space: O(Logn) if we consider the function call stack size, otherwise O(1).

Print BST keys in the given range

Given two values k1 and k2 (where k1 < k2) and a root pointer to a Binary Search Tree. Print all the keys of tree in range k1 to k2. i.e. print all x such that k1<=x<=k2 and x is a key of given BST. Print all the keys in increasing order. For example, if k1 = 10 and k2 = 22, then your function should print 12, 20 and 22.

Algorithm: 1) If value of roots key is greater than k1, then recursively call in left subtree. 2) If value of roots key is in range, then print the roots key. 3) If value of roots key is smaller than k2, then recursively call in right subtree. Implementation:
/* A tree node structure */ struct node { int data; struct node *left; struct node *right; }; /* The functions prints all the keys which in the given range [k1..k2]. The function assumes than k1 < k2 */ void Print(struct node *root, int k1, int k2) { /* base case */ if ( NULL == root ) return; /* Since the desired o/p is sorted, recurse for left subtree first If root->data is greater than k1, then only we can get o/p keys in left subtree */ if ( k1 < root->data ) Print(root->left, k1, k2); /* if root's data lies in range, then prints root's data */ if ( k1 <= root->data && k2 >= root->data ) printf("%d ", root->data );

/* If root->data is smaller than k2, then only we can get o/p keys in right subtree */ if ( k2 > root->data ) Print(root->right, k1, k2); }

Output: 12 20 22 Time Complexity: O(n) where n is the total number of keys in tree.

Print Ancestors of a given node in Binary Tree


Given a Binary Tree and a key, write a function that prints all the ancestors of the key in the given binary tree. For example, if the given tree is following Binary Tree and key is 7, then your function should print 4, 2 and 1.
1

/ / / 4 2 \ 5

\ 3

7 /* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; }; /* If target is present in tree, then prints the ancestors and returns true, otherwise returns false. */ bool printAncestors(struct node *root, int target) { /* base cases */ if ( root == NULL ) return false; if ( root->data == target ) return true; /* If target is present in either left or right subtree of this node, then print this node */ if ( printAncestors(root->left, target) ||

{ }

printAncestors(root->right, target) ) cout<<root->data<<" "; return true;

/* Else return false */ return false;

Output: 421 Time Complexity: O(n) where n is the number of nodes in the given Binary Tree.

Inorder Successor in Binary Search Tree


In Binary Tree, Inorder successor of a node is the next node in Inorder traversal of the Binary Tree. Inorder Successor is NULL for the last node in Inoorder traversal. In Binary Search Tree, Inorder Successor of an input node can also be defined as the node with the smallest key greater than the key of input node. So, it is sometimes important to find next node in sorted order.

In the above diagram, inorder successor of 8 is 10, inorder successor of 10 is 12 and inorder successor of 14 is 20. Algorithm to find Inorder Successor Algorithm is divided into two cases on the basis of right subtree of the input node being empty or not. Input: node, root // node is the node whose Inorder successor is needed. output: succ // succ is Inorder successor of node.

1) If right subtree of node is not NULL, then succ lies in right subtree. Do following. Go to right subtree and return the node with minimum key value in right subtree. 2) If right sbtree of node is NULL, then succ is one of the ancestors. Do following. Travel up using the parent pointer until you see a node which is left child of its parent. The parent of such a node is the succ. Implementation Note that the function to find InOrder Successor is highlighted (with gray background) in below code.
/* A binary tree and a pointer struct node { int data; struct node* struct node* struct node* }; node has data, pointer to left child to right child */

left; right; parent;

struct node * minValue(struct node* node); struct node * inOrderSuccessor(struct node *root, struct node *n) { // step 1 of the above algorithm if( n->right != NULL ) return minValue(n->right); // step 2 of the above algorithm struct node *p = n->parent; while(p != NULL && n == p->right) { n = p; p = p->parent; } return p;

} /* Given a non-empty binary search tree, return the minimum data value found in that tree. Note that the entire tree does not need to be searched. */ struct node * minValue(struct node* node) { struct node* current = node; /* loop down to find the leftmost leaf */ while (current->left != NULL) { current = current->left; } return current; }

Output of the above program: Inorder Successor of 14 is 20

Next higher number with same number of set bits


Given a number x, find next number with same number of 1 bits in its binary representation. For example, consider x = 12, whose binary representation is 1100 (excluding leading zeros on 32 bit machine). It contains two logic 1 bits. The next higher number with two logic 1 bits is 17 (100012). Algorithm: When we observe the binary sequence from 0 to 2n 1 (n is # of bits), right most bits (least significant) vary rapidly than left most bits. The idea is to find right most string of 1s in x, and shift the pattern to right extreme, except the left most bit in the pattern. Shift the left most bit in the pattern (omitted bit) to left part of x by one position. An example makes it more clear,
x = 15610 x = 10011100(2) 10011100 00011100 - right most string of 1's in x 00000011 - right shifted pattern except left most bit ------> [A] 00010000 - isolated left most bit of right most 1's pattern 00100000 - shiftleft-ed the isolated bit by one position ------> [B] 10000000 - left part of x, excluding right most 1's pattern ------> [C] 10100000 - add B and C (OR operation) ------> [D] 10100011 - add A and D which is required number 163(10)

After practicing with few examples, it easy to understand. Use the below given program for generating more sets. Program Design: We need to note few facts of binary numbers. The expression x & -x will isolate right most set bit in x (ensuring x will use 2s complement form for negative numbers). If we add the result to x, right most string of 1s in x will be reset, and the immediate 0 left to this pattern of 1s will be set, which is part [B] of above explanation. For example if x = 156, x & -x will result in 00000100, adding this result to x yields 10100000 (see part D). We left with the right shifting part of pattern of 1s (part A of above explanation). There are different ways to achieve part A. Right shifting is essentially a division operation. What should be our divisor? Clearly, it should be multiple of 2 (avoids 0.5 error in right shifting), and it should shift the right most 1s pattern to right extreme. The expression (x & -x) will serve the purpose of divisor. An EX-OR operation between the

number X and expression which is used to reset right most bits, will isolate the rightmost 1s pattern. A Correction Factor: Note that we are adding right most set bit to the bit pattern. The addition operation causes a shift in the bit positions. The weight of binary system is 2, one shift causes an increase by a factor of 2. Since the increased number (rightOnesPattern in the code) being used twice, the error propagates twice. The error needs to be corrected. A right shift by positions 2 will serve the purpose. The popular name for this program is same number of one bits. ?
#include<iostream> using namespace std; typedef unsigned int uint_t; // this function returns next higher number with same number of set bits as x. uint_t snoob(uint_t x) { uint_t rightOne; uint_t nextHigherOneBit; uint_t rightOnesPattern; uint_t next = 0; if(x) { // right most set bit rightOne = x & -(signed)x; // reset the pattern and set next higher bit // left part of x will be here nextHigherOneBit = x + rightOne; // nextHigherOneBit is now part [D] of the above explanation. // isolate the pattern rightOnesPattern = x ^ nextHigherOneBit; // right adjust pattern rightOnesPattern = (rightOnesPattern)/rightOne; // correction factor rightOnesPattern >>= 2;

// rightOnesPattern is now part [A] of the above explanation. // integrate new pattern (Add [D] and [A]) next = nextHigherOneBit | rightOnesPattern;

return next;

int main() { int x = 156; cout<<"Next higher number with same number of set bits is "<<snoob(x); getchar(); return 0; }

Usage: Finding/Generating subsets. Variations: 1. Write program to find a number immediately smaller than given, with same number of logic 1 bits? (Pretty simple) 2. How to count or generate the subsets available in the given set?

Turn an image by 90 degree


Given an image, how will you turn it by 90 degrees? An image can be treated as 2D matrix which can be stored in a buffer. We are provided with matrix dimensions and its base address. How can we turn it? For example see the below picture,
* * * * * * * * * * * * ^ | | | * * * * * * * * * * * *

After rotating right, it appears (observe arrow direction)


* * * * * * * * * * * * -- - - > * * * * * * * * * * * *

The idea is simple. Transform each row of source matrix into required column of final image. We will use an auxiliary buffer to transform the image. From the above picture, we can observe that
first row of source ------> last column of destination second row of source ------> last but-one column of destination so ... on last row of source ------> first column of destination

In pictorial form, we can represent the above transformations of an (m x n) matrix into (n x m) matrix,

Transformations If you have not attempted, atleast try your pseudo code now. It will be easy to write our pseudo code. In C/C++ we will usually traverse matrix on row major order. Each row is transformed into different column of final image. We need to construct columns of final image. See the following algorithm (transformation)
for(r = 0; r < m; r++) { for(c = 0; c < n; c++) { // Hint: Map each source element indices into // indices of destination matrix element. dest_buffer [ c ] [ m - r - 1 ] = source_buffer [ r ] [ c ]; } }

Note that there are various ways to implement the algorithm based on traversal of matrix, row major or column major order. We have two matrices and two ways (row and column major) to traverse each matrix. Hence, there can atleast be 4 different ways of transformation of source matrix into final matrix. Code:

void displayMatrix(unsigned int const *p, unsigned int row, unsigned int col); void rotate(unsigned int *pS, unsigned int *pD, unsigned int row, unsigned int col); int main() { // declarations unsigned int image[][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}; unsigned int *pSource; unsigned int *pDestination; unsigned int m, n; // setting initial values and memory allocation m = 3, n = 4, pSource = (unsigned int *)image; pDestination = (unsigned int *)malloc(sizeof(int)*m*n); // process each buffer displayMatrix(pSource, m, n); rotate(pSource, pDestination, m, n); displayMatrix(pDestination, n, m); free(pDestination); getchar(); return 0;

} void rotate(unsigned int *pS, unsigned int *pD, unsigned int row, unsigned int col) { unsigned int r, c; for(r = 0; r < row; r++) { for(c = 0; c < col; c++) { *(pD + c * row + (row - r - 1)) = *(pS + r * col + c); } } }

Stability in sorting algorithms


A sorting algorithm is said to be stable if two objects with equal keys appear in the same order in sorted output as they appear in the input unsorted array. Some sorting algorithms are stable by nature like Insertion sort, Merge Sort, Bubble Sort, etc. And some sorting algorithms are not, like Heap Sort, Quick Sort, etc.

However, any given sorting algo which is not stable can be modified to be stable. There can be sorting algo specific ways to make it stable, but in general, any comparison based sorting algorithm which is not stable by nature can be modified to be stable by changing the key comparison operation so that the comparison of two keys considers position as a factor for objects with equal keys.

When does the worst case of Quicksort occur?


The answer depends on strategy for choosing pivot. In early versions of Quick Sort where leftmost (or rightmost) element is chosen as pivot, the worst occurs in following cases. 1) Array is already sorted in same order. 2) Array is already sorted in reverse order. 3) All elements are same (special case of case 1 and 2) Since these cases are very common use cases, the problem was easily solved by choosing either a random index for the pivot, choosing the middle index of the partition or (especially for longer partitions) choosing the median of the first, middle and last element of the partition for the pivot. With these modifications, the worst case of Quick sort has less chances to occur, but worst case can still occur if the input array is such that the maximum (or minimum) element is always chosen as pivot.

Equilibrium index of an array


Equilibrium index of an array is an index such that the sum of elements at lower indexes is equal to the sum of elements at higher indexes. For example, in an arrya A: A[0] = -7, A[1] = 1, A[2] = 5, A[3] = 2, A[4] = -4, A[5] = 3, A[6]=0 3 is an equilibrium index, because: A[0] + A[1] + A[2] = A[4] + A[5] + A[6] 6 is also an equilibrium index, because sum of zero elements is zero, i.e., A[0] + A[1] + A[2] + A[3] + A[4] + A[5]=0 7 is not an equilibrium index, because it is not a valid index of array A. Write a function int equilibrium(int[] arr, int n); that given a sequence arr[] of size n, returns an equilibrium index (if any) or -1 if no equilibrium indexes exist. Method 1 (Simple but inefficient) Use two loops. Outer loop iterates through all the element and inner loop finds out

whether the current index picked by the outer loop is equilibrium index or not. Time complexity of this solution is O(n^2).
int equilibrium(int arr[], int n) { int i, j; int leftsum, rightsum; /* Check for indexes one by one until an equilibrium index is found */ for ( i = 0; i < n; ++i) { leftsum = 0; // initialize left sum for current index i rightsum = 0; // initialize right sum for current index i /* get left sum */ for ( j = 0; j < i; j++) leftsum += arr[j]; /* get right sum */ for( j = i+1; j < n; j++) rightsum += arr[j]; /* if leftsum and rightsum are same, then we are done */ if (leftsum == rightsum) return i; } /* return -1 if no equilibrium index is found */ return -1;

Time Complexity: O(n^2) Method 2 (Tricky and Efficient) The idea is to get total sum of array first. Then Iterate through the array and keep updating the left sum which is initialized as zero. In the loop, we can get right sum by subtracting the elements one by one.
1) Initialize leftsum as 0 2) Get the total sum of the array as sum 3) Iterate through the array and for each index i, do following. a) Update sum to get the right sum. sum = sum - arr[i] // sum is now right sum b) If leftsum is equal to sum, then return current index. c) leftsum = leftsum + arr[i] // update leftsum for next iteration. 4) return -1 // If we come out of loop without returning then // there is no equilibrium index

int equilibrium(int arr[], int n) { int sum = 0; // initialize sum of whole array int leftsum = 0; // initialize leftsum int i; /* Find sum of the whole array */ for (i = 0; i < n; ++i) sum += arr[i]; for( i = 0; i < n; ++i) { sum -= arr[i]; // sum is now right sum for index i if(leftsum == sum) return i; leftsum += arr[i]; } /* If no equilibrium index found, then return 0 */ return -1;

Time Complexity: O(n)

Find duplicates in O(n) time and O(1) extra space


Given an array of n elements which contains elements from 0 to n-1, with any of these numbers appearing any number of times. Find these repeating numbers in O(n) and using only constant memory space. For example, let n be 7 and array be {1, 2, 3, 1, 3, 0, 6}, the answer should be 1 & 3. This problem is an extended version of following problem. Find the two repeating elements in a given array Method 1 and Method 2 of the above link are not applicable as the question says O(n) time complexity and O(1) constant space. Also, Method 3 and Method 4 cannot be applied here because there can be more than 2 repeating elements in this problem. Method 5 can be extended to work for this problem. Below is the solution that is similar to the Method 5. Algorithm:
traverse the list for i= 0 to n-1 elements

check for sign of A[abs(A[i])] ; if positive then make it negative by A[abs(A[i])]=-A[abs(A[i])]; else // i.e., A[abs(A[i])] is negative this element (ith element of list) is a repetition

Implementation:
void printRepeating(int arr[], int size) { int i; printf("The repeating elements are: \n"); for(i = 0; i < size; i++) { if(arr[abs(arr[i])] >= 0) arr[abs(arr[i])] = -arr[abs(arr[i])]; else printf(" %d ", abs(arr[i])); } }

Note: The above program doesnt handle 0 case (If 0 is repeated). The program can be easily modified to handle that also. It is not handled to keep the code simple. Output: The repeating elements are: 13 Time Complexity: O(n) Auxiliary Space: O(1)

Sorted order printing of a given array that represents a BST


Given an array that stores a complete Binary Search Tree, write a function that efficiently prints the given array in ascending order. For example, given an array [4, 2, 5, 1, 3], the function should print 1, 2, 3, 4, 5

Solution: Inorder traversal of BST prints it in ascending order. The only trick is to modify recursion termination condition in standard Inorder Tree Traversal. Implementation:
void printSorted(int arr[], int start, int end) { if(start > end) return; // print left subtree printSorted(arr, start*2 + 1, end); // print root printf("%d ", arr[start]); // print right subtree printSorted(arr, start*2 + 2, end);

int main() { int arr[] = {4, 2, 5, 1, 3}; int arr_size = sizeof(arr)/sizeof(int); printSorted(arr, 0, arr_size-1); getchar(); return 0; }

Time Complexity: O(n)

Modulus on Negative Numbers


What will be the output of the following C program?
int main() { int a = 3, b = -8, c = 2; printf("%d", a % b / c); return 0; }

The output is 1. % and / have same precedence and left to right associativity. So % is performed first which results in 3 and / is performed next resulting in 1. The emphasis is, sign of left operand is appended to result in case of modulus operator in C.

Find the Minimum length Unsorted Subarray, sorting which makes the complete array sorted
Given an unsorted array arr[0..n-1] of size n, find the minimum length subarray arr[s..e] such that sorting this subarray makes the whole array sorted. Examples: 1) If the input array is [10, 12, 20, 30, 25, 40, 32, 31, 35, 50, 60], your program should be able to find that the subarray lies between the indexes 3 and 8. 2) If the input array is [0, 1, 15, 25, 6, 7, 30, 40, 50], your program should be able to find that the subarray lies between the indexes 2 and 5. Solution: 1) Find the candidate unsorted subarray a) Scan from left to right and find the first element which is greater than the next element. Let s be the index of such an element. In the above example 1, s is 3 (index of 30). b) Scan from right to left and find the first element (first in right to left order) which is smaller than the next element (next in right to left order). Let e be the index of such an element. In the above example 1, e is 7 (index of 31). 2) Check whether sorting the candidate unsorted subarray makes the complete array sorted or not. If not, then include more elements in the subarray. a) Find the minimum and maximum values in arr[s..e]. Let minimum and maximum values be min and max. min and max for [30, 25, 40, 32, 31] are 25 and 40 respectively. b) Find the first element (if there is any) in arr[0..s-1] which is greater than min, change s to index of this element. There is no such element in above example 1. c) Find the last element (if there is any) in arr[e+1..n-1] which is smaller than max, change e to index of this element. In the above example 1, e is changed to 8 (index of 35)

3) Print s and e. Implementation:


void printUnsorted(int arr[], int n) { int s = 0, e = n-1, i, max, min; // step 1(a) of above algo for (s = 0; s < n-1; s++) { if (arr[s] > arr[s+1]) break; } if (s == n-1) { printf("The complete array is sorted"); return; } // step 1(b) of above algo for(e = n - 1; e > 0; e--) { if(arr[e] < arr[e-1]) break; } // step 2(a) of above algo max = arr[s]; min = arr[s]; for(i = s + 1; i <= e; i++) { if(arr[i] > max) max = arr[i]; if(arr[i] < min) min = arr[i]; } // step 2(b) of above algo for( i = 0; i < s; i++) { if(arr[i] > min) { s = i; break; } } // step 2(c) of above algo for( i = n -1; i >= e+1; i--) { if(arr[i] < max) {

e = i; break; } }

// step 3 of above algo printf(" The unsorted subarray which makes the given array " " sorted lies between the indees %d and %d", s, e); return; } int main() { int arr[] = {10, 12, 20, 30, 25, 40, 32, 31, 35, 50, 60}; int arr_size = sizeof(arr)/sizeof(arr[0]); printUnsorted(arr, arr_size); getchar(); return 0; }

Time Complexity: O(n)

Print all combinations of balanced parentheses


Write a function to generate all possible n pairs of balanced parentheses. For example, if n=1 {} for n=2 {}{} {{}} Algorithm: Keep track of counts of open and close brackets. Initialize these counts as 0. Recursively call the _printParenthesis() function until open bracket count is less than the given n. If open bracket count becomes more than the close bracket count, then put a closing bracket and recursively call for the remaining brackets. If open bracket count is less than n, then put an opening bracket and call _printParenthesis() for the remaining brackets.
void _printParenthesis(int pos, int n, int open, int close); /* Wrapper over _printParenthesis()*/ void printParenthesis(int n) { if(n > 0) _printParenthesis(0, n, 0, 0); return; }

void _printParenthesis(int pos, int n, int open, int close) { static char str[MAX_SIZE]; if(close == n) { printf("%s \n", str); return; } else { if(open > close) { str[pos] = '}'; _printParenthesis(pos+1, n, open, close+1); } if(open < n) { str[pos] = '{'; _printParenthesis(pos+1, n, open+1, close); } }

Print nodes at k distance from root


Given a root of a tree, and an integer k. Print all the nodes which are at k distance from root. For example, in the below tree, 4, 5 & 8 are at distance 2 from root.
/ / 4 2 \ 5 8 1 \ / 3

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; }; void printKDistant(node *root , int k) { if(root == NULL) return; if( k == 0 ) { printf( "%d ", root->data );

return ; } else { printKDistant( root->left, k-1 ) ; printKDistant( root->right, k-1 ) ; }

int main() { printKDistant(root, 2); }

The above program prints 4, 5 and 8. Time Complexity: O(n) where n is number of nodes in the given binary tree.

Write you own Power without using multiplication (*) and division (/) operators
Method 1 (Using Nested Loops) We can calculate power by using repeated addition. For example to calculate 5^6. 1) First 5 times add 5, we get 25. (5^2) 2) Then 5 times add 25, we get 125. (5^3) 3) Then 5 time add 125, we get 625 (5^4) 4) Then 5 times add 625, we get 3125 (5^5) 5) Then 5 times add 3125, we get 15625 (5^6)
/* Works only if a >= 0 and b >= 0 */ int pow(int a, int b) { if (b == 0) return 1; int answer = a; int increment = a; int i, j; for(i = 1; i < b; i++) { for(j = 1; j < a; j++) { answer += increment; } increment = answer; }

return answer; }

Method 2 (Using Recursion) Recursively add a to get the multiplication of two numbers. And recursively multiply to get a raise to the power b.
#include<stdio.h> /* A recursive function to get a^b Works only if a >= 0 and b >= 0 */ int pow(int a, int b) { if(b) return multiply(a, pow(a, b-1)); else return 1; } /* A recursive function to get x*y */ int multiply(int x, int y) { if(y) return (x + multiply(x, y-1)); else return 0; } /* driver program to test above functions */ int main() { printf("\n %d", pow(5, 3)); getchar(); return 0; }

Turn off the rightmost set bit


Write a C function that unsets the rightmost set bit of an integer. Examples:
Input: 12 (00...01100) Output: 8 (00...01000) Input: 7 (00...00111) Output: 6 (00...00110)

Let the input number be n. n-1 would have all the bits flipped after the rightmost set bit (including the set bit). So, doing n&(n-1) would give us the required result.
/* unsets the rightmost set bit of n and returns the result */ int fun(unsigned int n)

return n&(n-1);

Foldable Binary Trees


Question: Given a binary tree, find out if the tree can be folded or not. A tree can be folded if left and right subtrees of the tree are structure wise mirror image of each other. An empty tree is considered as foldable.
Consider the below trees: (a) and (b) can be folded. (c) and (d) cannot be folded. (a) 7 / \ (b) / / 9 (c) 7 5 (d) 10 7 9 / / \ 10 \ 15 / 12 / / 11 10 \ 15 / 7 10 \ 15 \ 11 9 10 \ / 11 15

Method 1 (Change Left subtree to its Mirror and compare it with Right subtree) Algorithm: isFoldable(root)
1) If tree is empty, then return true. 2) Convert the left subtree to its mirror image mirror(root->left); /* See this post */ 3) Check if the structure of left subtree and right subtree is same and store the result.

res = isStructSame(root->left, root->right); /*isStructSame() recursively compares structures of two subtrees and returns true if structures are same */ 4) Revert the changes made in step (2) to get the original tree. mirror(root->left); 5) Return result res stored in step 2. struct node { int data; struct node* left; struct node* right; }; /* converts a tree to its mrror image */ void mirror(struct node* node); /* returns true if structure of two trees a and b is same Only structure is considered for comparison, not data! */ bool isStructSame(struct node *a, struct node *b); /* Returns true if the given tree is foldable */ bool isFoldable(struct node *root) { bool res; /* base case */ if(root == NULL) return true; /* convert left subtree to its mirror */ mirror(root->left); /* Compare the structures of the right subtree and mirrored left subtree */ res = isStructSame(root->left, root->right); /* Get the originial tree back */ mirror(root->left); return res;

bool { if { if

isStructSame(struct node *a, struct node *b)

(a == NULL && b == NULL) return true; } ( a != NULL && b != NULL && isStructSame(a->left, b->left) && isStructSame(a->right, b->right) ) { return true; }

return false;

/* UTILITY FUNCTIONS */ /* Change a tree so that the roles of the left and right pointers are swapped at every node. See http://geeksforgeeks.org/?p=662 for details */ void mirror(struct node* node) { if (node==NULL) return; else { struct node* temp; /* do the subtrees */ mirror(node->left); mirror(node->right); /* swap the temp node->left node->right } } pointers in this node */ = node->left; = node->right; = temp;

Time complexity: O(n) Method 2 (Check if Left and Right subtrees are Mirror) There are mainly two functions: // Checks if tree can be folded or not
IsFoldable(root) 1) If tree is empty then return true 2) Else check if left and right subtrees are structure wise mirrors of each other. Use utility function IsFoldableUtil(root->left, root->right) for this.

// Checks if n1 and n2 are mirror of each other.


IsFoldableUtil(n1, n2) 1) If both trees are empty then return true. 2) If one of them is empty and other is not then return false. 3) Return true if following conditions are met a) n1->left is mirror of n2->right b) n1->right is mirror of n2->left struct node { int data; struct node* left; struct node* right;

}; /* A utility function that checks if trees with roots as n1 and n2 are mirror of each other */ bool IsFoldableUtil(struct node *n1, struct node *n2); /* Returns true if the given tree can be folded */ bool IsFoldable(struct node *root) { if (root == NULL) { return true; } return IsFoldableUtil(root->left, root->right);

/* A utility function that checks if trees with roots as n1 and n2 are mirror of each other */ bool IsFoldableUtil(struct node *n1, struct node *n2) { /* If both left and right subtrees are NULL, then return true */ if (n1 == NULL && n2 == NULL) { return true; } /* If one of the trees is NULL and other is not, then return false */ if (n1 == NULL || n2 == NULL) { return false; } /* Otherwise check if left and right subtrees are mirrors of their counterparts */ return IsFoldableUtil(n1->left, n2->right) && IsFoldableUtil(n1->right, n2->left);

Reverse a Linked List in groups of given size


Given a linked list, write a function to reverse every k nodes (where k is an input to the function).
Example: Inputs: 1->2->3->4->5->6->7->8->NULL and k = 3 Output: 3->2->1->6->5->4->8->7->NULL. Inputs: Output: 1->2->3->4->5->6->7->80->NULL and k = 5 5->4->3->2->1->8->7->6->NULL.

Algorithm: reverse(head, k) 1) Reverse the first sub-list of size k. While reversing keep track of the next node and previous node. Let the pointer to the next node be next and pointer to the previous node be prev. See this post for reversing a linked list. 2) head->next = reverse(next, k) /* Recursively call for rest of the list and link the two sub-lists */ 3) return prev /* prev becomes the new head of the list (see the diagrams of iterative method of this post) */
/* Link list node */ struct node { int data; struct node* next; }; /* Reverses the linked list in groups of size k and returns the pointer to the new head node */ struct node *reverse (struct node *head, int k) { struct node* current = head; struct node* next; struct node* prev = NULL; int count = 0; /*reverse first k nodes of the linked list */ while (current != NULL && count < k) { next = current->next; current->next = prev; prev = current; current = next; count++; } /* next is now a pointer to (k+1)th node Recursively call for the list starting from current. And make rest of the list as next of first node */ if(next != NULL) { head->next = reverse(next, k); } /* prev is new head of the input list */ return prev; }

Find the two repeating elements in a given array

You are given an array of n+2 elements. All elements of the array are in range 1 to n. And all elements occur once except two numbers which occur twice. Find the two repeating numbers. For example, array = {4, 2, 4, 5, 2, 3, 1} and n = 5 The above array has n + 2 = 7 elements with all elements occurring once except 2 and 4 which occur twice. So the output should be 4 2. Method 1 (Basic) Use two loops. In the outer loop, pick elements one by one and count the number of occurrences of the picked element in the inner loop. This method doesnt use the other useful data provided in questions like range of numbers is between 1 to n and there are only two repeating elements.
void printRepeating(int arr[], int size) { int i, j; printf(" Repeating elements are "); for(i = 0; i < size; i++) for(j = i+1; j < size; j++) if(arr[i] == arr[j]) printf(" %d ", arr[i]); }

Time Complexity: O(n*n) Auxiliary Space: O(1) Method 2 (Use Count array) Traverse the array once. While traversing, keep track of count of all elements in the array using a temp array count[] of size n, when you see an element whose count is already set, print it as duplicate. This method uses the range given in the question to restrict the size of count[], but doesnt use the data that there are only two repeating elements.
void printRepeating(int arr[], int size) { int *count = (int *)calloc(sizeof(int), (size - 2)); int i; printf(" Repeating elements are "); for(i = 0; i < size; i++) { if(count[arr[i]] == 1) printf(" %d ", arr[i]); else count[arr[i]]++; }

Time Complexity: O(n) Auxiliary Space: O(n) Method 3 (Make two equations) We have to find two numbers, so two unknowns. We know the sum of n numbers is n(n+1)/2 and product is n!. Make two equations using these sum and product formulas, and get values of two unknowns using the two equations. Let summation of all numbers in array be S and product be P Let the numbers which are being repeated are X and Y. X + Y = S n(n+1)/2 XY = P/n! Using above two equations, we can find out X and Y. For array = 4 2 4 5 2 3 1, we get S = 21 and P as 960. X + Y = 21 15 = 6 XY = 960/5! = 8 X Y = sqrt((X+Y)^2 4*XY) = sqrt(4) = 2 Using below two equations, we easily get X = (6 + 2)/2 and Y = (6-2)/2 X+Y=6 XY=2 Time Complexity: O(n) Auxiliary Space: O(1) Method 4 (Use XOR) Let the repeating numbers be X and Y, if we xor all the elements in the array and all integers from 1 to n, then the result is X xor Y. The 1s in binary representation of X xor Y is corresponding to the different bits between X and Y. Suppose that the kth bit of X xor Y is 1, we can xor all the elements in the array and all integers from 1 to n, whose kth bits are 1. The result will be one of X and Y.
void printRepeating(int arr[], int size) { int xor = arr[0]; /* Will hold xor of all elements */ int set_bit_no; /* Will have only single set bit of xor */ int i; int n = size - 2; int x = 0, y = 0;

/* Get the xor of all elements in arr[] and {1, 2 .. n} */ for(i = 0; i < size; i++) xor ^= arr[i]; for(i = 1; i <= n; i++) xor ^= i; /* Get the rightmost set bit in set_bit_no */ set_bit_no = xor & ~(xor-1); /* Now divide elements in two sets by comparing rightmost set bit of xor with bit at same position in each element. */ for(i = 0; i < size; i++) { if(arr[i] & set_bit_no) x = x ^ arr[i]; /*XOR of first set in arr[] */ else y = y ^ arr[i]; /*XOR of second set in arr[] */ } for(i = 1; i <= n; i++) { if(i & set_bit_no) x = x ^ i; /*XOR of first set in arr[] and {1, 2, ...n }*/ else y = y ^ i; /*XOR of second set in arr[] and {1, 2, ...n } */ } printf("\n The two repeating elements are %d & %d ", x, y); }

Method 5 (Use array elements as index)

traverse the list for i= 1st to n+2 elements { check for sign of A[abs(A[i])] ; if positive then make it negative by A[abs(A[i])]=-A[abs(A[i])]; else // i.e., A[abs(A[i])] is negative this element (ith element of list) is a repetition } void printRepeating(int arr[], int size) { int i; printf("\n The repeating elements are"); for(i = 0; i < size; i++) { if(arr[abs(arr[i])] > 0) arr[abs(arr[i])] = -arr[abs(arr[i])]; else printf(" %d ", abs(arr[i])); } }

Segregate Even and Odd numbers


Given an array A[], write a function that segregates even and odd numbers. The functions should put all even numbers first, and then odd numbers. Example Input = {12, 34, 45, 9, 8, 90, 3} Output = {12, 34, 8, 90, 45, 9, 3} In the output, order of numbers can be changed, i.e., in the above example 34 can come before 12 and 3 can come before 9. The problem is very similar to our old post Segregate 0s and 1s in an array, and both of these problems are variation of famous Dutch national flag problem.
Algorithm: segregateEvenOdd() 1) Initialize two index variables left and right: left = 0, right = size -1 2) Keep incrementing left index until we see an odd number. 3) Keep decrementing right index until we see an even number. 4) If lef < right then swap arr[left] and arr[right]

Implementation:
/* Function to swap *a and *b */ void swap(int *a, int *b); void segregateEvenOdd(int arr[], int size) { /* Initialize left and right indexes */ int left = 0, right = size-1; while(left < right) { /* Increment left index while we see 0 at left */ while(arr[left]%2 == 0 && left < right) left++; /* Decrement right index while we see 1 at right */ while(arr[right]%2 == 1 && left < right) right--; if(left < right) { /* Swap arr[left] and arr[right]*/ swap(&arr[left], &arr[right]);

left++; right--; } } /* UTILITY FUNCTIONS */ void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } }

Time Complexity: O(n)

Identical Linked Lists


Two Linked Lists are identical when they have same data and arrangement of data is also same. For example Linked lists a (1->2->3) and b(1->2->3) are identical. . Write a function to check if the given two linked lists are identical. Method 1 (Iterative) To identify if two lists are identical, we need to traverse both lists simultaneously, and while traversing we need to compare data.
/* Structure for a linked list node */ struct node { int data; struct node *next; }; /* returns 1 if linked lists a and b are identical, otherwise 0 */ bool areIdentical(struct node *a, struct node *b) { while(1) { /* base case */ if(a == NULL && b == NULL) { return 1; } if(a == NULL && b != NULL) { return 0; } if(a != NULL && b == NULL) { return 0; } if(a->data != b->data) { return 0; } /* If we reach here, then a and b are not NULL and their data is same, so move to next nodes in both lists */ a = a->next;

} }

b = b->next;

Method 2 (Recursive) Recursive solution code is much cleaner than the iterative code. You probably wouldnt want to use the recursive version for production code however, because it will use stack space which is proportional to the length of the lists
bool { if { if { if { if { areIdentical(struct node *a, struct node *b) (a == NULL && b == NULL) return 1; } (a == NULL && b != NULL) return 0; } (a != NULL && b == NULL) return 0; } (a->data != b->data) return 0; }

/* If we reach here, then a and b are not NULL and their data is same, so move to next nodes in both lists */ return areIdentical(a->next, b->next); }

Time Complexity: O(n) for both iterative and recursive versions. n is the length of the smaller list among a and b.

Alternating split of a given Singly Linked List


Write a function AlternatingSplit() that takes one list and divides up its nodes to make two smaller lists a and b. The sublists should be made from alternating elements in the original list. So if the original list is 0->1->0->1->0->1 then one sublist should be 0->0>0 and the other should be 1->1->1. Method 1(Simple) The simplest approach iterates over the source list and pull nodes off the source and alternately put them at the front (or beginning) of a and b. The only strange part is that the nodes will be in the reverse order that they occurred in the source list. Method 2 inserts the node at the end by keeping track of last node in sublists.
/*Program to alternatively split a linked list into two halves */ /* Link list node */ struct node { int data; struct node* next; };

/* pull off the front node of the source and put it in dest */ void MoveNode(struct node** destRef, struct node** sourceRef) ; /* Given the source list, split its nodes into two shorter lists. If we number the elements 0, 1, 2, ... then all the even elements should go in the first list, and all the odd elements in the second. The elements in the new lists may be in any order. */ void AlternatingSplit(struct node* source, struct node** aRef, struct node** bRef) { /* split the nodes of source to these 'a' and 'b' lists */ struct node* a = NULL; struct node* b = NULL; struct node* current = source; while (current != NULL) { MoveNode(&a, &current); /* Move a node to list 'a' */ if (current != NULL) { MoveNode(&b, &current); /* Move a node to list 'b' */ } } *aRef = a; *bRef = b;

/* Take the node from the front of the source, and move it to the front of the dest. It is an error to call this with the source list empty. Before calling MoveNode(): source == {1, 2, 3} dest == {1, 2, 3} Affter calling MoveNode(): source == {2, 3} dest == {1, 1, 2, 3}

*/ void MoveNode(struct node** destRef, struct node** sourceRef) { /* the front source node */ struct node* newNode = *sourceRef; assert(newNode != NULL); /* Advance the source pointer */ *sourceRef = newNode->next; /* Link the old dest off the new node */ newNode->next = *destRef; /* Move dest to point to the new node */ *destRef = newNode;

Time Complexity: O(n) where n is number of node in the given linked list.

Method 2(Using Dummy Nodes) Here is an alternative approach which builds the sub-lists in the same order as the source list. The code uses a temporary dummy header nodes for the a and b lists as they are being built. Each sublist has a tail pointer which points to its current last node that way new nodes can be appended to the end of each list easily. The dummy nodes give the tail pointers something to point to initially. The dummy nodes are efficient in this case because they are temporary and allocated in the stack. Alternately, local reference pointers (which always points to the last pointer in the list instead of to the last node) could be used to avoid Dummy nodes.
void AlternatingSplit(struct node* source, struct node** aRef, struct node** bRef) { struct node aDummy; struct node* aTail = &aDummy; /* points to the last node in 'a' */ struct node bDummy; struct node* bTail = &bDummy; /* points to the last node in 'b' */ struct node* current = source; aDummy.next = NULL; bDummy.next = NULL; while (current != NULL) { MoveNode(&(aTail->next), &current); /* add at 'a' tail */ aTail = aTail->next; /* advance the 'a' tail */ if (current != NULL) { MoveNode(&(bTail->next), &current); bTail = bTail->next; } } *aRef = aDummy.next; *bRef = bDummy.next; }

Time Complexity: O(n) where n is number of node in the given linked list.

Delete alternate nodes of a Linked List


Given a Singly Linked List, starting from the second node delete all alternate nodes of it. For example, if the given linked list is 1->2->3->4->5 then your function should convert it to 1->3->5, and if the given linked list is 1->2->3->4 then convert it to 1->3. Method 1 (Iterative) Keep track of previous of the node to be deleted. First change the next link of previous node and then free the memory allocated for the node.

/* A linked list node */ struct node { int data; struct node *next; }; /* deletes alternate nodes of a list starting with head */ void deleteAlt(struct node *head) { if (head == NULL) return; /* Initialize prev and node to be deleted */ struct node *prev = head; struct node *node = head->next; while (prev != NULL && node != NULL) { /* Change next link of previous node */ prev->next = node->next; /* Free memory */ free(node); /* Update prev and node */ prev = prev->next; if(prev != NULL) node = prev->next;

} }

Time Complexity: O(n) where n is the number of nodes in the given Linked List. Method 2 (Recursive) Recursive code uses the same approach as method 1. The recursive code is simple and short, but causes O(n) recursive function calls for a linked list of size n.
/* deletes alternate nodes of a list starting with head */ void deleteAlt(struct node *head) { if (head == NULL) return; struct node *node = head->next; if (node == NULL) return;

/* Change the next link of head */ head->next = node->next; /* free memory allocated for node */ free(node); /* Recursively call for the new next of head */ deleteAlt(head->next); }

Time Complexity: O(n)

Maximum width of a binary tree


Given a binary tree, write a function to get the maximum width of the given tree. Width of a tree is maximum of widths of all levels. Let us consider the below example tree.
1 2 4 / / \ 5 6 \ 3 \ / 8 \ 7

For the above tree, width of level 1 is 1, width of level 2 is 2, width of level 3 is 3 width of level 4 is 2. So the maximum width of the tree is 3. Algortihm: There are basically two functions. One is to count nodes at a given level (getWidth), and other is to get the maximum width of the tree(getMaxWidth). getMaxWidth() makes use of getWidth() to get the width of all levels starting from root.
/*Function to print level order traversal of tree*/ getMaxWidth(tree) maxWdth = 0 for i = 1 to height(tree) width = getWidth(tree, i); if(width > maxWdth) maxWdth = width return width /*Function to get width of a given level */ getWidth(tree, level)

if tree is NULL then return 0; if level is 1, then return 1; else if level greater than 1, then return getWidth(tree->left, level-1) + getWidth(tree->right, level-1);

Implementation:
/* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

/*Function protoypes*/ int getWidth(struct node* root, int level); int height(struct node* node); struct node* newNode(int data); /* Function to get the maximum width of a binary tree*/ int getMaxWidth(struct node* root) { int maxWidth = 0; int width; int h = height(root); int i; /* Get width of each level and compare the width with maximum width so far */ for(i=1; i<=h; i++) { width = getWidth(root, i); if(width > maxWidth) maxWidth = width; } return maxWidth; } /* Get width of a given level */ int getWidth(struct node* root, int level) { if(root == NULL) return 0; if(level == 1) return 1;

else if (level > 1) return getWidth(root->left, level-1) + getWidth(root->right, level-1); }

Intersection of two Sorted Linked Lists


Given two lists sorted in increasing order, create and return a new list representing the intersection of the two lists. The new list should be made with its own memory the original lists should not be changed. For example, let the first linked list be 1->2->3->4->6 and second linked list be 2->4->6>8, then your function should create and return a third list as 2->4->6. Method 1 (Using Dummy Node) The strategy here uses a temporary dummy node as the start of the result list. The pointer tail always points to the last node in the result list, so appending new nodes is easy. The dummy node gives tail something to point to initially when the result list is empty. This dummy node is efficient, since it is only temporary, and it is allocated in the stack. The loop proceeds, removing one node from either a or b, and adding it to tail. When we are done, the result is in dummy.next.
/* Link list node */ struct node { int data; struct node* next; }; /*This solution uses the temporary dummy to build up the result list */ struct node* sortedIntersect(struct node* a, struct node* b) { struct node dummy; struct node* tail = &dummy; dummy.next = NULL; /* Once one or the other list runs out -- we're done */ while (a != NULL && b != NULL) { if(a->data == b->data) { push((&tail->next), a->data); tail = tail->next; a = a->next; b = b->next; } else if (a->data < b->data) {

/* advance the smaller list */ a = a->next; } else { b = b->next; }

} return(dummy.next);

/* UTILITY FUNCTIONS */ /* Function to insert a node at the beginging of the linked list */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node)); /* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref); /* move the head to point to the new node */ (*head_ref) = new_node;

Time Complexity: O(n) where n is the number of nodes in the smaller list. Method 2 (Using Local References) This solution is structurally very similar to the above, but it avoids using a dummy node Instead, it maintains a struct node** pointer, lastPtrRef, that always points to the last pointer of the result list. This solves the same case that the dummy node did dealing with the result list when it is empty. If you are trying to build up a list at its tail, either the dummy node or the struct node** reference strategy can be used?
/* Link list node */ struct node { int data; struct node* next; }; void push(struct node** head_ref, int new_data); /* This solution uses the local reference */ struct node* sortedIntersect(struct node* a, struct node* b) { struct node* result = NULL; struct node** lastPtrRef = &result;

/* Advance comparing the first nodes in both lists. When one or the other list runs out, we're done. */ while (a!=NULL && b!=NULL) { if(a->data == b->data) { /* found a node for the intersection */ push(lastPtrRef, a->data); lastPtrRef = &((*lastPtrRef)->next); a = a->next; b = b->next; } else if (a->data < b->data) { /* advance the smaller list */ a=a->next; } else { b=b->next; } } return(result);

/* Function to insert a node at the beginging of the linked list */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node)); /* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref); /* move the head to point to the new node */ (*head_ref) = new_node;

Time Complexity: O(n) where n is the number of nodes in the smaller list. Method 3 (Recursive) Below is the recursive implementation of sortedIntersect(). The method expects three parameters. The initial value passed as third parameter must be NULL.
/* Link list node */ struct node { int data; struct node* next;

}; struct node *sortedIntersect(struct node *a, struct node *b, struct node *result) { /* base case */ if(a == NULL || b == NULL) { return NULL; } /* If both lists are non-empty */ /* advance the smaller list and call recursively */ if(a->data < b->data) { return sortedIntersect(a->next, b, result); } else if(a->data > b->data) { return sortedIntersect(a, b->next, result); } else if(a->data == b->data) { /* If same data is found then allocate memory */ struct node *temp = (struct node *)malloc(sizeof(struct node)); temp->data = a->data; /* If the first node is being added to resultant list */ if(result == NULL) { result = temp; } /* Else change the next of result and move result to next */ else { result->next = temp; result = temp; } /* advance both lists and call recursively */ result->next = sortedIntersect(a->next, b->next, result);

return result;

/* UTILITY FUNCTIONS */ /* Function to insert a node at the beginging of the linked list */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref); /* move the head to point to the new node */ (*head_ref) = new_node; }

Time Complexity: O(n) where n is the number of nodes in the smaller list. Please write comments if you find the above codes/algorithms incorrect, or find better ways to solve the same problem

Run Length Encoding


Given an input string, write a function that returns the Run Length Encoded string for the input string. For example, if the input string is wwwwaaadexxxxxx, then the function should return w4a3d1e1x6. Algorithm: a) Pick the first character from source string. b) Append the picked character to the destination string. c) Count the number of subsequent occurrences of the picked character and append the count to destination string. d) Pick the next character and repeat steps b) c) and d) if end of string is NOT reached.
#define MAX_RLEN 50 /* Returns the Run Length Encoded string for the source string src */ char *encode(char *src) { int rLen; char count[MAX_RLEN]; int len = strlen(src); /* If all characters in the source string are different, then size of destination string would be twice of input string. For example if the src is "abcd", then dest would be "a1b1c1" For other inputs, size would be less than twice. */ char *dest = (char *)malloc(sizeof(char)*(len*2 + 1)); int i, j = 0, k; /* traverse the input string one by one */

for(i = 0; i < len; i++) { /* Copy the first occurrence of the new character */ dest[j++] = src[i]; /* Count the number of occurrences of the new character */ rLen = 1; while(i + 1 < len && src[i] == src[i+1]) { rLen++; i++; } /* Store rLen in a character array count[] */ sprintf(count, "%d", rLen); /* Copy the count[] to destination */ for(k = 0; *(count+k); k++, j++) { dest[j] = count[k]; } } /*terminate the destination string */ dest[j] = '\0'; return dest; } /*driver program to test above function */ int main() { char str[] = "geeksforgeeks"; char *res = encode(str); printf("%s", res); getchar(); }

Time Complexity: O(n)

Print all combinations of points that can compose a given number


You can win three kinds of basketball points, 1 point, 2 points, and 3 points. Given a total score n, print out all the combination to compose n. Examples: For n = 1, the program should print following: 1

For n = 2, the program should print following: 11 2 For n = 3, the program should print following: 111 12 21 3 For n = 4, the program should print following: 1111 112 121 13 211 22 31 and so on Algorithm: At first position we can have three numbers 1 or 2 or 3. First put 1 at first position and recursively call for n-1. Then put 2 at first position and recursively call for n-2. Then put 3 at first position and recursively call for n-3. If n becomes 0 then we have formed a combination that compose n, so print the current combination. Below is a generalized implementation. In the below implementation, we can change MAX_POINT if there are higher points (more than 3) in the basketball game.
#define MAX_POINT 3 #define ARR_SIZE 100 /* Utility function to print array arr[] */ void printArray(int arr[], int arr_size); /* The function prints all combinations of numbers 1, 2, ...MAX_POINT that sum up to n. i is used in recursion keep track of index in arr[] where next element is to be added. Initital value of i must be passed as 0 */ void printCompositions(int n, int i) { /* array must be static as we want to keep track of values stored in arr[] using current calls of printCompositions() in function call stack*/ static int arr[ARR_SIZE];

if (n == 0) { printArray(arr, i); } else if(n > 0) { int k; for (k = 1; k <= MAX_POINT; k++) { arr[i]= k; printCompositions(n-k, i+1); } }

/* UTILITY FUNCTIONS */ /* Utility function to print array arr[] */ void printArray(int arr[], int arr_size) { int i; for (i = 0; i < arr_size; i++) printf("%d ", arr[i]); printf("\n"); } /* Driver function to test above functions */ int main() { int n = 5; printf("Differnt compositions formed by 1, 2 and 3 of %d are\n", n); printCompositions(n, 0); getchar(); return 0; }

Sort an array of 0s, 1s and 2s


Given an array A[] consisting 0s, 1s and 2s, write a function that sorts A[]. The functions should put all 0s first, then all 1s and all 2s in last. Example Input = {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}; Output = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2} The problem is similar to our old post Segregate 0s and 1s in an array, and both of these problems are variation of famous Dutch national flag problem. The problem was posed with three colours, here `0, `1 and `2. The array is divided into four sections:

1. 2. 3. 4.

a[1..Lo-1] zeroes (red) a[Lo..Mid-] ones (white) a[Mid..Hi] unknown a[Hi+1..N] twos (blue)

The unknown region is shrunk while maintaining these conditions 1. 2. Lo := 1; Mid := 1; Hi := N; while Mid <= Hi do 1. Invariant: a[1..Lo-1]=0 and a[Lo..Mid-1]=1 and a[Hi+1..N]=2; a[Mid..Hi] are unknown. 2. case a[Mid] in 0: swap a[Lo] and a[Mid]; Lo++; Mid++ 1: Mid++ 2: swap a[Mid] and a[Hi]; Hi

Dutch National Flag Algorithm, or 3-way Partitioning Part way through the process, some red, white and blue elements are known and are in the right place. The section of unknown elements, a[Mid..Hi], is shrunk by examining a[Mid]:
| 0 0 0 1 1 1 ? ? ? ? 2 2 2 ^ ^ ^ | | | Lo Mid Hi

Examine a[Mid]. There are three possibilities: a[Mid] is (0) red, (1) white or (2) blue. Case (0) a[Mid] is red, swap a[Lo] and a[Mid]; Lo++; Mid++
0 0 0 0 1 ^ ^ | | Lo Mid 1 1 ? ? ? 2 2 2 ^ | Hi

Case (1) a[Mid] is white, Mid++


0 0 0 1 1 1 ^ ^ | | Lo Mid 1 ? ? ? 2 2 2 ^ | Hi

Case (2) a[Mid] is blue, swap a[Mid] and a[Hi]; Hi


0 0 0 1 1 ^ ^ | | Lo Mid 1 ? ? ? 2 2 2 2 ^ | Hi

Continue until Mid>Hi.


/* Function to swap *a and *b */ void swap(int *a, int *b); void sort012(int a[], int arr_size) { int lo = 0; int hi = arr_size - 1; int mid = 0; while(mid <= hi) { switch(a[mid]) { case 0: swap(&a[lo++], &a[mid++]); break; case 1: mid++; break; case 2: swap(&a[mid], &a[hi--]); break; } } } /* UTILITY FUNCTIONS */ void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }

Time Complexity: O(n) The above code performs unnecessary swaps for inputs like 0 0 0 0 1 1 1 2 2 2 2 2 : lo=4 and mid=7 and hi=11. In present code: first 7 exchanged with 11 and hi become 10 and mid is still pointing to 7. again same operation is till the mid <= hi. But it is really not required. We can put following loop before switch condition to make sure that hi is pointing to location which is not 2 so that it would eliminate unnecessary swaps of 2.
while ((a[hi]==2) && hi >= mid) hi; if (hi<mid) break;

Segregate 0s and 1s in an array


You are given an array of 0s and 1s in random order. Segregate 0s on left side and 1s on right side of the array. Traverse array only once.
Input array = [0, 1, 0, 1, 0, 0, 1, 1, 1, 0] Output array = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]

Method 1 (Count 0s or 1s) 1) Count the number of 0s. Let count be C. 2) Once we have count, we can put C 0s at the beginning and 1s at the remaining n C positions in array. Time Complexity: O(n) The method 1 traverses the array two times. Method 2 does the same in a single pass.

Method 2 (Use two indexes to traverse) Maintain two indexes. Initialize first index left as 0 and second index right as n-1. Do following while left < right a) Keep incrementing index left while there are 0s at it b) Keep decrementing index right while there are 1s at it c) If left < right then exchange arr[left] and arr[right] Implementation:
/*Function to put all 0s on left and all 1s on right*/ void segregate0and1(int arr[], int size) { /* Initialize left and right indexes */ int left = 0, right = size-1; while(left < right) { /* Increment left index while we see 0 at left */ while(arr[left] == 0 && left < right) left++; /* Decrement right index while we see 1 at right */

while(arr[right] == 1 && left < right) right; /* If left is smaller than right then there is a 1 at left and a 0 at right. Exchange arr[left] and arr[right]*/ if(left < right) { arr[left] = 0; arr[right] = 1; left++; right; }

} }

Time Complexity: O(n)

Pairwise swap elements of a given linked list


Given a singly linked list, write a function to swap elements pairwise. For example, if the linked list is 1->2->3->4->5 then the function should change it to 2->1->4->3->5, and if the linked list is 1->2->3->4->5->6 then the function should change it to 2->1->4->3->6>5. METHOD 1 (Iterative) Start from the head node and traverse the list. While traversing swap data of each node with its next nodes data.
/* A linked list node */ struct node { int data; struct node *next; }; /*Function to swap two integers at addresses a and b */ void swap(int *a, int *b); /* Function to pairwise swap elements of a linked list */ void pairWiseSwap(struct node *head) { struct node *temp = head; /* Traverse further only if there are at-least two nodes left */ while(temp != NULL && temp->next != NULL) { /* Swap data of node with its next node's data */

swap(&temp->data, &temp->next->data); /* Move temp by 2 for the next pair */ temp = temp->next->next;

} }

void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; }

Time complexity: O (n) METHOD 2 (Recursive) If there are 2 or more than 2 nodes in Linked List then swap the first two nodes and recursively call for rest of the list.
/* Recursive function to pairwise swap elements of a linked list */ void pairWiseSwap(struct node *head) { /* There must be at-least two nodes in the list */ if(head != NULL && head->next != NULL) { /* Swap the node's data with data of next node */ swap(&head->data, &head->next->data); /* Call pairWiseSwap() for rest of the list */ pairWiseSwap(head->next->next); } }

Time complexity: O (n)

Union and Intersection of two sorted arrays


For example, if the input arrays are: arr1[] = {1, 3, 4, 5, 7} arr2[] = {2, 3, 5, 6} Then your program should print Union as {1, 2, 3, 4, 5, 6, 7} and Intersection as {3, 5}. Algorithm Union (arr1 [], arr2 []): For union of two arrays, follow the following merge procedure. 1) Use two index variables i and j, initial values i = 0, j = 0 2) If arr1 [i] is smaller than arr2 [j] then print arr1 [i] and increment i. 3) If arr1 [i] is greater than arr2 [j] then print arr2 [j] and increment j.

4) If both are same then print any of them and increment both i and j. 5) Print remaining elements of the larger array.
/* Function prints union of arr1[] and arr2[] m is the number of elements in arr1[] n is the number of elements in arr2[] */ int printUnion(int arr1[], int arr2[], int m, int n) { int i = 0, j = 0; while(i < m && j < n) { if(arr1[i] < arr2[j]) printf(" %d ", arr1[i++]); else if(arr2[j] < arr1[i]) printf(" %d ", arr2[j++]); else { printf(" %d ", arr2[j++]); i++; } } /* Print remaining elements of the larger array */ while(i < m) printf(" %d ", arr1[i++]); while(j < n) printf(" %d ", arr2[j++]);

Time Complexity: O(m+n) Algorithm Intersection (arr1 [], arr2 []): For Intersection of two arrays, print the element only if the element is present in both arrays. 1) Use two index variables i and j, initial values i = 0, j = 0 2) If arr1[i] is smaller than arr2[j] then increment i. 3) If arr1[i] is greater than arr2[j] then increment j. 4) If both are same then print any of them and increment both i and j.
/* Function prints Intersection of arr1[] and arr2[] m is the number of elements in arr1[] n is the number of elements in arr2[] */ int printIntersection(int arr1[], int arr2[], int m, int n) { int i = 0, j = 0; while(i < m && j < n) { if(arr1[i] < arr2[j]) i++; else if(arr2[j] < arr1[i]) j++;

} }

else /* if arr1[i] == arr2[j] */ { printf(" %d ", arr2[j++]); i++; }

Time Complexity: O(m+n)

Reverse a stack using recursion


You are not allowed to use loop constructs like while, for.etc, and you can only use the following ADT functions on Stack S: isEmpty(S) push(S) pop(S) Solution: The idea of the solution is to hold all values in Function Call Stack until the stack becomes empty. When the stack becomes empty, insert all held items one by one at the bottom of the stack. For example, let the input stack be
1 <-- top 2 3 4 First 4 are inserted at the bottom. 4 <-- top Then 3 is inserted at the bottom 4 <-- top 3 Then 2 is inserted at the bottom 4 <-- top 3 2 Then 1 is inserted at the bottom 4 <-- top 3 2 1

So we need a function that inserts at the bottom of a stack using the above given basic stack function. //Below is a recursive function that inserts an element at the bottom of a stack.

void insertAtBottom(struct sNode** top_ref, int item) { int temp; if(isEmpty(*top_ref)) { push(top_ref, item); } else { /* Hold all items in Function Call Stack until we reach end of the stack. When the stack becomes empty, the isEmpty(*top_ref) becomes true, the above if part is executed and the item is inserted at the bottom */ temp = pop(top_ref); insertAtBottom(top_ref, item); /* Once the item is inserted at the bottom, push all the items held in Function Call Stack */ push(top_ref, temp);

} }

//Below is the function that reverses the given stack using insertAtBottom()
void reverse(struct sNode** top_ref) { int temp; if(!isEmpty(*top_ref)) { /* Hold all items in Function Call Stack until we reach end of the stack */ temp = pop(top_ref); reverse(top_ref); /* Insert all the items (held in Function Call Stack) one by one from the bottom to top. Every item is inserted at the bottom */ insertAtBottom(top_ref, temp);

} }

//Below is a complete running program for testing above functions.


#define bool int /* structure of a stack node */ struct sNode { char data; struct sNode *next; }; /* Driveer program to test above functions */

int main() { struct sNode *s = NULL; push(&s, 4); push(&s, 3); push(&s, 2); push(&s, 1); printf("\n Original Stack "); print(s); reverse(&s); printf("\n Reversed Stack "); print(s); getchar();

Median of two sorted arrays


Question: There are 2 sorted arrays A and B of size n each. Write an algorithm to find the median of the array obtained after merging the above 2 arrays(i.e. array of length 2n). The complexity should be O(log(n)) Median: In probability theory and statistics, a median is described as the number separating the higher half of a sample, a population, or a probability distribution, from the lower half. The median of a finite list of numbers can be found by arranging all the numbers from lowest value to highest value and picking the middle one. For getting the median of input array { 12, 11, 15, 10, 20 }, first sort the array. We get { 10, 11, 12, 15, 20 } after sorting. Median is the middle element of the sorted array which is 12. There are different conventions to take median of an array with even number of elements, one can take the mean of the two middle values, or first middle value, or second middle value. Let us see different methods to get the median of two sorted arrays of size n each. Since size of the set for which we are looking for median is even (2n), we are taking average of two middle two numbers in all below solutions. Method 1 (Simply count while Merging) Use merge procedure of merge sort. Keep track of count while comparing elements of two arrays. If count becomes n(For 2n elements), we have reached the median. Take the average of the elements at indexes n-1 and n in the merged array. See the below implementation. Implementation:

/* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { int i = 0; /* Current index of i/p array ar1[] */ int j = 0; /* Current index of i/p array ar2[] */ int count; int m1 = -1, m2 = -1; /* Since there are 2n elements, median will be average of elements at index n-1 and n in the array obtained after merging ar1 and ar2 */ for(count = 0; count <= n; count++) { /*Below is to handle case where all elements of ar1[] are smaller than smallest(or first) element of ar2[]*/ if(i == n) { m1 = m2; m2 = ar2[0]; break; } /*Below is to handle case where all elements of ar2[] are smaller than smallest(or first) element of ar1[]*/ else if(j == n) { m1 = m2; m2 = ar1[0]; break; } if(ar1[i] < ar2[j]) { m1 = m2; /* Store the prev median */ m2 = ar1[i]; i++; } else { m1 = m2; /* Store the prev median */ m2 = ar2[j]; j++; }

return (m1 + m2)/2;

Time Complexity: O(n)

Method 2 (By comparing the medians of two arrays) This method works by first getting medians of the two sorted arrays and then comparing them. Let ar1 and ar2 be the input arrays. Algorithm:
1) Calculate the medians m1 and m2 of the input arrays ar1[] and ar2[] respectively. 2) If m1 and m2 both are equal then we are done. return m1 (or m2) 3) If m1 is greater than m2, then median is present in one of the below two subarrays. a) From first element of ar1 to m1 (ar1[0...|_n/2_|]) b) From m2 to last element of ar2 (ar2[|_n/2_|...n-1]) 4) If m2 is greater than m1, then median is present in one of the below two subarrays. a) From m1 to last element of ar1 (ar1[|_n/2_|...n-1]) b) From first element of ar2 to m2 (ar2[0...|_n/2_|]) 5) Repeat the above process until size of both the subarrays becomes 2. 6) If size of the two arrays is 2 then use below formula to get the median. Median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2

Example:
ar1[] = {1, 12, 15, 26, 38} ar2[] = {2, 13, 17, 30, 45}

For above two arrays m1 = 15 and m2 = 17 For the above ar1[] and ar2[], m1 is smaller than m2. So median is present in one of the following two subarrays.
[15, 26, 38] and [2, 13, 17]

Let us repeat the process for above two subarrays:


m1 = 26 m2 = 13.

m1 is greater than m2. So the subarrays become


[15, 26] and [13, 17] Now size is 2, so median = = = = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2 (max(15, 13) + min(26, 17))/2 (15 + 17)/2 16

Implementation:

#include<stdio.h> int max(int, int); /* to get maximum of two integers */ int min(int, int); /* to get minimum of two integeres */ int median(int [], int); /* to get median of a single array */ /* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { int m1; /* For median of ar1 */ int m2; /* For median of ar2 */ /* return -1 if(n <= 0) return -1; for invalid input */

if(n == 1) return (ar1[0] + ar2[0])/2; if (n == 2) return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2; m1 = median(ar1, n); /* get the median of the first array */ m2 = median(ar2, n); /* get the median of the second array */ /* If medians are equal then return either m1 or m2 */ if(m1 == m2) return m1; /* if m1 < m2 then median must exist in ar1[m1....] and ar2[....m2] */ if (m1 < m2) return getMedian(ar1 + n/2, ar2, n - n/2); /* if m1 > m2 then median must exist in ar1[....m1] and ar2[m2...] */ return getMedian(ar2 + n/2, ar1, n - n/2);

} /* Function to get median of a single array */ int median(int arr[], int n) { if(n%2 == 0) return (arr[n/2] + arr[n/2-1])/2; else return arr[n/2]; }

Time Complexity: O(logn) Algorithmic Paradigm: Divide and Conquer

Method 3 (By doing binary search for the median): The basic idea is that if you are given two arrays ar1[] and ar2[] and know the length of each, you can check whether an element ar1[i] is the median in constant time. Suppose that the median is ar1[i]. Since the array is sorted, it is greater than exactly i-1 values in array ar1[]. Then if it is the median, it is also greater than exactly j = n i 1 elements in ar2[]. It requires constant time to check if ar2[j] <= ar1[i] <= ar2[j + 1]. If ar1[i] is not the median, then depending on whether ar1[i] is greater or less than ar2[j] and ar2[j + 1], you know that ar1[i] is either greater than or less than the median. Thus you can binary search for median in O(lg n) worst-case time. For two arrays ar1 and ar2, first do binary search in ar1[]. If you reach at the end (left or right) of the first array and don't find median, start searching in the second array ar2[].
1) Get the middle element of ar1[] using array indexes left and right. Let index of the middle element be i. 2) Calculate the corresponding index j of ar2[] j = n i 1 3) If ar1[i] >= ar2[j] and ar1[i] <= ar2[j+1] then ar1[i] and ar2[j] are the middle elements. return average of ar2[j] and ar1[i] 4) If ar1[i] is greater than both ar2[j] and ar2[j+1] then do binary search in left half (i.e., arr[left ... i-1]) 5) If ar1[i] is smaller than both ar2[j] and ar2[j+1] then do binary search in right half (i.e., arr[i+1....right]) 6) If you reach at any corner of ar1[] then do binary search in ar2[]

Example:
ar1[] = {1, 5, 7, 10, 13} ar2[] = {11, 15, 23, 30, 45}

Middle element of ar1[] is 7. Let us compare 7 with 23 and 30, since 7 smaller than both 23 and 30, move to right in ar1[]. Do binary search in {10, 13}, this step will pick 10. Now compare 10 with 15 and 23. Since 10 is smaller than both 15 and 23, again move to right. Only 13 is there in right side now. Since 13 is greater than 11 and smaller than 15, terminate here. We have got the median as 12 (average of 11 and 13) Implementation:
int getMedianRec(int ar1[], int ar2[], int left, int right, int n); /* This function returns median of Assumptions in this function: Both ar1[] and ar2[] are sorted Both have n elements */ int getMedian(int ar1[], int ar2[], { return getMedianRec(ar1, ar2, 0, } ar1[] and ar2[]. arrays int n) n-1, n);

/* A recursive function to get the median of ar1[] and ar2[] using binary search */ int getMedianRec(int ar1[], int ar2[], int left, int right, int n) { int i, j; /* We have reached at the end (left or right) of ar1[] */ if(left > right) return getMedianRec(ar2, ar1, 0, n-1, n); i = (left + right)/2; j = n - i - 1; /* Index of ar2[] */ /* Recursion terminates here.*/ if(ar1[i] > ar2[j] && (j == n-1 || ar1[i] <= ar2[j+1])) { /*ar1[i] is decided as median 2, now select the median 1 (element just before ar1[i] in merged array) to get the average of both*/ if(ar2[j] > ar1[i-1] || i == 0) return (ar1[i] + ar2[j])/2; else return (ar1[i] + ar1[i-1])/2; } /*Search in left half of ar1[]*/ else if (ar1[i] > ar2[j] && j != n-1 && ar1[i] > ar2[j+1]) return getMedianRec(ar1, ar2, left, i-1, n); /*Search in right half of ar1[]*/ else /* ar1[i] is smaller than both ar2[j] and ar2[j+1]*/ return getMedianRec(ar1, ar2, i+1, right, n);

/* Driver program to test above function */ int main() { int ar1[] = {1, 12, 15, 26, 38}; int ar2[] = {2, 13, 17, 30, 45}; printf("%d", getMedian(ar1, ar2, 5)) ; getchar(); return 0; }

Time Complexity: O(logn)

Given a binary tree, print all root-to-leaf paths


For the below example tree, all root-to-leaf paths are: 10 > 8 > 3

10 > 8 > 5 10 > 2 > 2

Algorithm: Use a path array path[] to store current root to leaf path. Traverse from root to all leaves in top-down fashion. While traversing, store data of all nodes in current path in array path[]. When we reach a leaf node, print the path array.
/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; }; /*Given a binary tree, print out all of its root-to-leaf paths, one per line. Uses a recursive helper to do the work.*/ void printPaths(struct node* node) { int path[1000]; printPathsRecur(node, path, 0); } /* Recursive helper function -- given a node, and an array containing the path from the root node up to but not including this node, print out all the root-leaf paths.*/ void printPathsRecur(struct node* node, int path[], int pathLen) { if (node==NULL) return; /* append this node to the path array */ path[pathLen] = node->data; pathLen++; /* it's a leaf, so print the path that led to here if (node->left==NULL && node->right==NULL) { printArray(path, pathLen); } else { /* otherwise try both subtrees */ printPathsRecur(node->left, path, pathLen); */

} }

printPathsRecur(node->right, path, pathLen);

/* Utility that prints out an array on a line. */ void printArray(int ints[], int len) { int i; for (i=0; i<len; i++) { printf("%d ", ints[i]); } printf("\n"); }

Time Complexity: O(n)

Root to leaf path sum equal to a given number


Given a binary tree and a number, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals the given number. Return false if no such path can be found.

For example, in the above tree root to leaf paths exist with following sums. 21 > 10 8 3 23 > 10 8 5 14 > 10 2 2 So the returned value should be true only for numbers 21, 23 and 14. For any other number, returned value should be false. Algorithm: Recursively check if left or right child has path sum equal to ( number value at current node) Implementation:
#define bool int

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; }; /* Given a tree and a sum, return true if there is a path from the root down to a leaf, such that adding up all the values along the path equals the given sum. Strategy: subtract the node value from the sum when recurring down, and check to see if the sum is 0 when you run out of tree. */ bool hasPathSum(struct node* node, int sum) { /* return true if we run out of tree and sum==0 */ if (node == NULL) { return(sum == 0); } else { /* otherwise check both subtrees */ int subSum = sum - node->data; return(hasPathSum(node->left, subSum) || hasPathSum(node->right, subSum)); } }

Time Complexity: O(n)

Maximum size square sub-matrix with all 1s


Given a binary matrix, find out the maximum size square sub-matrix with all 1s. For example, consider the below binary matrix.
0 1 0 1 1 0 1 1 1 1 1 0 1 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 1 0

The maximum square sub-matrix with all set bits is

1 1 1

1 1 1

1 1 1

Algorithm: Let the given binary matrix be M[R][C]. The idea of the algorithm is to construct an auxiliary size matrix S[][] in which each entry S[i][j] represents size of the square submatrix with all 1s including M[i][j] and M[i][j] is the rightmost and bottommost entry in sub-matrix.
1) Construct a sum matrix S[R][C] for the given M[R][C]. a) Copy first row and first columns as it is from M[][] to S[][] b) For other entries, use following expressions to construct S[][] If M[i][j] is 1 then S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1 Else /*If M[i][j] is 0*/ S[i][j] = 0 2) Find the maximum entry in S[R][C] 3) Using the value and coordinates of maximum entry in S[i], print sub-matrix of M[][]

For the given M[R][C] in above example, constructed S[R][C] would be:
0 1 0 1 1 0 1 1 1 1 2 0 1 0 1 2 2 0 0 1 1 2 3 0 1 0 0 0 1 0

The value of maximum entry in above matrix is 3 and coordinates of the entry are (4, 3). Using the maximum value and its coordinates, we can find out the required sub-matrix.
#define bool int #define R 6 #define C 5 void printMaxSubSquare(bool M[R][C]) { int i,j; int S[R][C]; int max_of_s, max_i, max_j; /* Set first column of S[][]*/ for(i = 0; i < R; i++) S[i][0] = M[i][0]; /* Set first row of S[][]*/ for(j = 0; j < C; j++) S[0][j] = M[0][j]; /* Construct other entries of S[][]*/ for(i = 1; i < R; i++)

for(j = 1; j < C; j++) { if(M[i][j] == 1) S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1; else S[i][j] = 0; }

} /* Find the maximum entry, and indexes of maximum entry in S[][] */ max_of_s = S[0][0]; max_i = 0; max_j = 0; for(i = 0; i < R; i++) { for(j = 0; j < C; j++) { if(max_of_s < S[i][j]) { max_of_s = S[i][j]; max_i = i; max_j = j; } } } printf("\n Maximum size sub-matrix is: \n"); for(i = max_i; i > max_i - max_of_s; i--) { for(j = max_j; j > max_j - max_of_s; j--) { printf("%d ", M[i][j]); } printf("\n"); }

Time Complexity: O(m*n) where m is number of rows and n is number of columns in the given matrix. Auxiliary Space: O(m*n) where m is number of rows and n is number of columns in the given matrix. Algorithmic Paradigm: Dynamic Programming

Print list items containing all characters of a given word


There is a list of items. Given a specific word, e.g., sun, print out all the items in list which contain all the characters of sun For example if the given word is sun and the items are sunday, geeksforgeeks, utensils, just and sss, then the program should print sunday and utensils. Algorithm: Thanks to geek4u for suggesting this algorithm.

1) Initialize a binary map: map[256] = {0, 0, ..} 2) Set values in map[] for the given word "sun" map['s'] = 1, map['u'] = 1, map['n'] = 1 3) Store length of the word "sun": len = 3 for "sun" 4) Pick words (or items)one by one from the list a) set count = 0; b) For each character ch of the picked word if(map['ch'] is set) increment count and unset map['ch'] c) If count becomes equal to len (3 for "sun"), print the currently picked word. d) Set values in map[] for next list item map['s'] = 1, map['u'] = 1, map['n'] = 1 # define NO_OF_CHARS 256 /* prints list items having all caharacters of word */ void print(char *list[], char *word, int list_size) { /*Since calloc is used, map[] is initialized as 0 */ int *map = (int *)calloc(sizeof(int), NO_OF_CHARS); int i, j, count, word_size; /*Set the values in map */ for (i = 0; *(word+i); i++) map[*(word + i)] = 1; /* Get the length of given word */ word_size = strlen(word); /* Check each item of list if has all characters of word*/ for (i = 0; i < list_size; i++) { for(j = 0, count = 0; *(list[i] + j); j++) { if(map[*(list[i] + j)]) { count++; /* unset the bit so that strings like sss not printed*/ map[*(list[i] + j)] = 0; } } if(count == word_size) printf("\n %s", list[i]); /*Set the values in map for next item*/ for (j = 0; *(word+j); j++) map[*(word + j)] = 1;

} }

Time Complexity: O(n + m) where n is total number of characters in the list of items. And m = (number of items in list) * (number of characters in the given word)

Maximum difference between two elements


Given an array arr[] of integers, find out the difference between any two elements such that larger element appears after the smaller number in arr[]. Examples: If array is [2, 3, 10, 6, 4, 8, 1] then returned value should be 8 (Diff between 10 and 2). If array is [ 7, 9, 5, 6, 3, 2 ] then returned value should be 2 (Diff between 7 and 9) Method 1 (Simple) Use two loops. In the outer loop, pick elements one by one and in the inner loop calculate the difference of the picked element with every other element in the array and compare the difference with the maximum difference calculated so far.
/* The function assumes that there are at least two elements in array. The function returns a negative value if the array is sorted in decreasing order. Returns 0 if elements are equal */ int maxDiff(int arr[], int arr_size) { int max_diff = arr[1] - arr[0]; int i, j; for(i = 0; i < arr_size; i++) { for(j = i+1; j < arr_size; j++) { if(arr[j] - arr[i] > max_diff) max_diff = arr[j] - arr[i]; } } return max_diff; }

Time Complexity: O(n^2) Method 2 (Tricky and Efficient) In this method, instead of taking difference of the picked element with every other element, we take the difference with the minimum

element found so far. So we need to keep track of 2 things: 1) Maximum difference found so far (max_diff). 2) Minimum number visited so far (min_element).
/* The function assumes that there are at least two elements in array. The function returns a negative value if the array is

sorted in decreasing order. Returns 0 if elements are equal */ int maxDiff(int arr[], int arr_size) { int max_diff = arr[1] - arr[0]; int min_element = arr[0]; int i; for(i = 1; i < arr_size; i++) { if(arr[i] - min_element > max_diff) max_diff = arr[i] - min_element; if(arr[i] < min_element) min_element = arr[i]; } return max_diff; }

Time Complexity: O(n)

Remove duplicates from an unsorted linked list


Write a removeDuplicates() function which takes a list and deletes any duplicate nodes from the list. The list is not sorted. For example if the linked list is 12->11->12->21->41->43->21 then removeDuplicates() should convert the list to 12->11->21->41->43. METHOD 1 (Using two loops) This is the simple way where two loops are used. Outer loop is used to pick the elements one by one and inner loop compares the picked element with rest of the elements.
/* Program to remove duplicates in an unsorted array */ struct node { int data; struct node *next; }; /* Function to remove duplicates from a unsorted linked list */ void removeDuplicates(struct node *start) { struct node *ptr1, *ptr2, *dup; ptr1 = start; /* Pick elements one by one */ while(ptr1 != NULL && ptr1->next != NULL) { ptr2 = ptr1; /* Compare the picked element with rest of the elements */

while(ptr2->next != NULL) { /* If duplicate then delete it */ if(ptr1->data == ptr2->next->data) { /* sequence of steps is important here */ dup = ptr2->next; ptr2->next = ptr2->next->next; free(dup); } else /* This is tricky */ { ptr2 = ptr2->next; } } ptr1 = ptr1->next; } }

Time Complexity: O(n^2) METHOD 2 (Use Sorting) In general, Merge Sort is the best suited sorting algorithm for sorting linked lists efficiently. 1) Sort the elements using Merge Sort. We will soon be writing a post about sorting a linked list. O(nLogn) 2) Remove duplicates in linear time using the algorithm for removing duplicates in sorted Linked List. O(n) Time Complexity: O(nLogn) METHOD 3 (Use Hashing) We traverse the link list from head to end. For the newly encountered element, we check whether it is in the hash table: if yes, we remove it; otherwise we put it in the hash table. Time Complexity: O(n) on average (assuming that hash table access time is O(1) on average).

Remove duplicates from a sorted linked list


Write a removeDuplicates() function which takes a list sorted in non-decreasing order and deletes any duplicate nodes from the list. The list should only be traversed once. For example if the linked list is 11->11->11->21->43->43->60 then removeDuplicates() should convert the list to 11->21->43->60. Algorithm: Traverse the list from the head (or start) node. While traversing, compare each node with its next node. If data of next node is same as current node then delete the next node. Before we delete a node, we need to store next pointer of the node

Implementation: Functions other than removeDuplicates() are just to create a linked linked list and test removeDuplicates().
/*Program to remove duplicates from a sorted linked list */ struct node { int data; struct node* next; }; /* The function removes duplicates from a sorted list */ void removeDuplicates(struct node* head) { /* Pointer to traverse the linked list */ struct node* current = head; /* Pointer to store the next pointer of a node to be deleted*/ struct node* next_next; /* do nothing if the list is empty */ if(current == NULL) return; /* Traverse the list till last node */ while(current->next != NULL) { /* Compare current node with next node */ if(current->data == current->next->data) { /*The sequence of steps is important*/ next_next = current->next->next; free(current->next); current->next = next_next; } else /* This is tricky: only advance if no deletion */ { current = current->next; } }

Time Complexity: O(n) where n is number of nodes in the given linked list.

Maximum and minimum of an array using minimum number of comparisons


Write a C function to return minimum and maximum in an array. You program should make minimum number of comparisons. First of all, how do we return multiple values from a C function? We can do it either using structures or pointers. We have created a structure named pair (which contains min and max) to return multiple values.
struct pair { int min; int max; };

And the function declaration becomes: struct pair getMinMax(int arr[], int n) where arr[] is the array of size n whose minimum and maximum are needed. METHOD 1 (Simple Linear Search) Initialize values of min and max as minimum and maximum of the first two elements respectively. Starting from 3rd, compare each element with max and min, and change max and min accordingly (i.e., if the element is smaller than min then change min, else if the element is greater than max then change max, else ignore the element) Time Complexity: O(n) In this method, total number of comparisons is 1 + 2(n-2) in worst case and 1 + n 2 in best case. In the above implementation, worst case occurs when elements are sorted in descending order and best case occurs when elements are sorted in ascending order. METHOD 2 (Tournament Method) Divide the array into two parts and compare the maximums and minimums of the the two parts to get the maximum and the minimum of the the whole array.
Pair MaxMin(array, array_size) if array_size = 1

return element as both max and min else if arry_size = 2 one comparison to determine max and min return that pair else /* array_size > 2 */ recur for max and min of left half recur for max and min of right half one comparison determines true max of the two candidates one comparison determines true min of the two candidates return the pair of max and min

Implementation
/* structure is used to return two values from minMax() */ struct pair { int min; int max; }; struct pair getMinMax(int arr[], int low, int high) { struct pair minmax, mml, mmr; int mid; /* If there is only on element */ if(low == high) { minmax.max = arr[low]; minmax.min = arr[low]; return minmax; } /* If there are two elements */ if(high == low + 1) { if(arr[low] > arr[high]) { minmax.max = arr[low]; minmax.min = arr[high]; } else { minmax.max = arr[high]; minmax.min = arr[low]; } return minmax; } /* If mid = mml = mmr = there are more than 2 elements */ (low + high)/2; getMinMax(arr, low, mid); getMinMax(arr, mid+1, high);

/* compare minimums of two parts*/

if(mml.min < mmr.min) minmax.min = mml.min; else minmax.min = mmr.min; /* compare maximums of two parts*/ if(mml.max > mmr.max) minmax.max = mml.max; else minmax.max = mmr.max; return minmax; }

Time Complexity: O(n) Total number of comparisons: let number of comparisons be T(n). T(n) can be written as follows: Algorithmic Paradigm: Divide and Conquer
T(n) = T(floor(n/2)) + T(ceil(n/2)) + 2 T(2) = 1 T(1) = 0

If n is a power of 2, then we can write T(n) as:


T(n) = 2T(n/2) + 2

After solving above recursion, we get


T(n) = 3/2n -2

Thus, the approach does 3/2n -2 comparisons if n is a power of 2. And it does more than 3/2n -2 comparisons if n is not a power of 2.

METHOD 3 (Compare in Pairs) If n is odd then initialize min and max as first element. If n is even then initialize min and max as minimum and maximum of the first two elements respectively. For rest of the elements, pick them in pairs and compare their maximum and minimum with max and min respectively.
/* structure is used to return two values from minMax() */ struct pair { int min; int max; };

struct pair getMinMax(int arr[], int n) { struct pair minmax; int i; /* If array has even number of elements then initialize the first two elements as minimum and maximum */ if(n%2 == 0) { if(arr[0] > arr[1]) { minmax.max = arr[0]; minmax.min = arr[1]; } else { minmax.min = arr[0]; minmax.max = arr[1]; } i = 2; /* set the startung index for loop */ } /* If array initialize maximum */ else { minmax.min minmax.max i = 1; /* } has odd number of elements then the first element as minimum and

= arr[0]; = arr[0]; set the startung index for loop */

/* In the while loop, pick elements in pair and compare the pair with max and min so far */ while(i < n-1) { if(arr[i] > arr[i+1]) { if(arr[i] > minmax.max) minmax.max = arr[i]; if(arr[i+1] < minmax.min) minmax.min = arr[i+1]; } else { if(arr[i+1] > minmax.max) minmax.max = arr[i+1]; if(arr[i] < minmax.min) minmax.min = arr[i]; } i += 2; /* Increment the index by 2 as two elements are processed in loop */ }

return minmax;

Time Complexity: O(n) Total number of comparisons: Different for even and odd n, see below:
If n is odd: If n is even: max, elements = 3*(n-1)/2 1 Initial comparison for initializing min and and 3(n-2)/2 comparisons for rest of the 1 + 3*(n-2)/2 = 3n/2 -2

Second and third approaches make equal number of comparisons when n is a power of 2. In general, method 3 seems to be the best.

Convert an arbitrary Binary Tree to a tree that holds Children Sum Property
Question: Given an arbitrary binary tree, convert it to a binary tree that holds Children Sum Property. You can only increment data values in any node. For example, the below tree doesnt hold the children sum property, convert it to a tree that holds the property.
/ 7 / \ / \ 5 1 50 \ \ / 2 /\

/ 3

\ 30

Algorithm: Traverse given tree in post order to convert it, i.e., first change left and right children to hold the children sum property then change the parent node. Let difference between nodes data and children sum be diff.
diff = nodes children sum - nodes data

If diff is 0 then nothing needs to be done. If diff > 0 ( nodes data is smaller than nodes children sum) increment the nodes data by diff.

If diff < 0 (nodes data is greater than the node's children sum) then increment one childs data. We can choose to increment either left or right child. Let us always increment the left child. Incrementing a child changes the subtrees children sum property so we need to change left subtree also. Left subtree is fixed by incrementing all the children in left subtree by diff, we have a function increment() for this purpose (see below C code). Let us run the algorithm for the given example. First convert the left subtree (increment 7 to 8).
/ 8 / \ / \ 5 1 50 \ \ / 2 /\

/ 3

\ 30

Then convert the right subtree (increment 2 to 31)


50 / / \ 3 / \ 5 1 / 8 / \ \ 31 / \ \ 30

Now convert the root, we have to increment left subtree for converting the root.
/ 19 / \ / \ 5 1 50 \ \ / 31 / \

/ 14

\ 30

Please note the last step we have incremented 8 to 19, and to fix the subtree we have incremented 3 to 14. Implementation:
/* Program to convert an aribitary binary tree to a tree that holds children sum property */ struct node { int data; struct node* left; struct node* right; };

/* This function is used to increment left subtree */ void increment(struct node* node, int diff); /* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data);

/* This function changes a tree to to hold children sum property */ void convertTree(struct node* node) { int left_data = 0, right_data = 0, diff; /* If tree is empty or it's a leaf node then return true */ if(node == NULL || (node->left == NULL && node->right == NULL)) return; else { /* convert left and right subtrees */ convertTree(node->left); convertTree(node->right); /* If left child is not present then 0 is used as data of left child */ if(node->left != NULL) left_data = node->left->data; /*If right child is not present then 0 is used as data of right child */ if(node->right != NULL) right_data = node->right->data; /* get the diff of node's data and children sum */ diff = left_data + right_data - node->data; /* If node's data is smaller than children sum,then increment node's data by diff */ if(diff > 0) node->data = node->data + diff; /* THIS IS TRICKY --> If node's data is greater than children sum, then increment left subtree by diff */ if(diff < 0) increment(node, -diff); } } /* This function is used to increment left subtree */ void increment(struct node* node, int diff) { /* This if is for the case where left child is NULL */ if(node->left == NULL) { node->left = newNode(diff); return;

} /* Go in depth, and fix all left children */ while(node->left != NULL) { node->left->data = node->left->data + diff; node = node->left; }

Time Complexity: O(n^2), Worst case complexity is for a skewed tree such that nodes are in decreasing order from root to leaf. Now extend the above question for an n-ary tree.

Check for Children Sum Property in a Binary Tree.


Given a binary tree, write a function that returns true if the tree satisfies below property. For every node, data value must be equal to sum of data values in left and right children. Consider data value as 0 for NULL children. Below tree is an example

Algorithm: Traverse the given binary tree. For each node check (recursively) if the node and both its children satisfy the Children Sum Property, if so then return true else return false. Implementation:
struct node { int data; struct node* left; struct node* right; }; /* returns 1 if children sum property holds for the given node and both of its children*/ int isSumProperty(struct node* node) {

/* left_data is left child data and right_data is for right child data*/ int left_data = 0, right_data = 0; /* If node is NULL or it's a leaf node then return true */ if(node == NULL || (node->left == NULL && node->right == NULL)) return 1; else { /* If left child is not present then 0 is used as data of left child */ if(node->left != NULL) left_data = node->left->data; /* If right child is not present then 0 is used as data of right child */ if(node->right != NULL) right_data = node->right->data; /* if the node and both of its children satisfy the property return 1 else 0*/ if((node->data == left_data + right_data)&& isSumProperty(node->left) && isSumProperty(node->right)) return 1; else return 0;

} }

Time Complexity: O(n), we are doing a complete traversal of the tree.

Two elements whose sum is closest to zero


Question: An Array of integers is given, both +ve and -ve. You need to find the two elements such that their sum is closest to zero. For the below array, program should print -80 and 85.

METHOD 1 (Simple) For each element, find the sum of it with every other element in the array and compare sums. Finally, return the minimum sum. Implementation
void minAbsSumPair(int arr[], int arr_size) {

int inv_count = 0; int l, r, min_sum, sum, min_l, min_r; /* Array should have at least two elements*/ if(arr_size < 2) { printf("Invalid Input"); return; } /* Initialization of values */ min_l = 0; min_r = 1; min_sum = arr[0] + arr[1]; for(l = 0; l < arr_size - 1; l++) { for(r = l+1; r < arr_size; r++) { sum = arr[l] + arr[r]; if(abs(min_sum) > abs(sum)) { min_sum = sum; min_l = l; min_r = r; } } } printf(" The two elements whose sum is minimum are %d and %d", arr[min_l], arr[min_r]);

Time complexity: O(n^2)

METHOD 2 (Use Sorting) Algorithm 1) Sort all the elements of the array. 2) Find the index of first positive element, this is initial value of right index r. 3) Initialize: left index l = r 1. min_sum = INT_MIN 4) In a loop, look for the candidates by comparing sum with minimum sum. If arr[l] + arr[r] becomes negative then increment the right index r, else decrement left index l. Implementation
void quickSort(int *, int, int); /* Function to print pair of elements having minimum sum */ void minAbsSumPair(int arr[], int arr_size) {

int l, r = 0, min_sum, sum = 0, min_l, min_r; /* Array should have at least two elements*/ if(arr_size < 2) { printf("Invalid Input"); return; } /* Sort the elements */ quickSort(arr, 0, arr_size-1); /* Find the first positive element. Note that we have condition "r < arr_size -1" -1 is there to handle the cases when all elements are negative */ while(arr[r] < 0 && r < arr_size - 1) r++; /* If all elements are positive then first two elements are the minimum sum elements */ if(r == 0) { printf(" The first two elements %d and %d have minimum sum", arr[0], arr[1]); return; } /* Start looking for the pair from the first positive element and last negative element */ l = r - 1; min_sum = arr[l] + arr[r]; min_l = l; /* min_l is for the left element of minimum sum pair*/ min_r = r; /* min_r is for the right element of minimum sum pair*/ while(l >= 0 && r < arr_size) { sum = arr[l] + arr[r]; /*If abs(sum) is less then update the result items*/ if(abs(sum) < abs(min_sum)) { min_sum = sum; min_l = l; min_r = r; } if(sum < 0) r++; else l--; } printf(" The two elements whose sum is minimum are %d and %d", arr[min_l], arr[min_r]);

Example:
Input array: = 1, 60, -10, 70, -80, 85 1) Sort the array arr[] = -80, -10, 1, 60, 70, 85 2) Find the index of first positive element r = 2 3) Initialize: l = r - 1 = 1, sum = min_sum = A[l] + A[r] = -10 + 1 = -9 Now loop for getting the minimum a) Since sum < 0, inrement r. r is now 3 sum = -10 + 60 = 50 b) Since sum > 0, decrement l. l is now 0 sum = -80 + 60 = -50 c) Since sum < 0, increment r. r is now 4 sum = -80 + 70 = -10 d) Since sum < 0, increment r. r is now 5 sum = -80 + 85 = 5, min_sum is updated to 5 as abs(sum) < abs(min_sum)

Time Complexity: complexity to sort + complexity to find the index of first positive + complexity of finding pair = O(nlogn) if we use nlogn sorting algorithm + O(n) + O(n) = O(nlogn)

Count Inversions in an array


Inversion Count for an array indicates how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum. Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j Example: The sequence 2, 4, 1, 3, 5 has three inversions (2, 1), (4, 1), (4, 3). METHOD 1 (Simple) For each element, count number of elements which are on right side of it and are smaller than it.
int getInvCount(int arr[], int n) { int inv_count = 0; int i, j; for(i = 0; i < n - 1; i++) for(j = i+1; j < n; j++) if(arr[i] > arr[j]) inv_count++;

return inv_count;

Time Complexity: O(n^2)

METHOD 2(Enhance Merge Sort) Suppose we know the number of inversions in the left half and right half of the array (let be inv1 and inv2), what kinds of inversions are not accounted for in Inv1 + Inv2? The answer is the inversions we have to count during the merge step. Therefore, to get number of inversions, we need to add number of inversions in left subarray, right subarray and merge().

How to get number of inversions in merge()? In merge process, let i is used for indexing left sub-array and j for right sub-array. At any step in merge(), if a[i] is greater than a[j], then there are (mid i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] a[mid]) will be greater than a[j]

The complete picture:

Implementation:
#include <stdio.h> #include <stdlib.h> int _mergeSort(int arr[], int temp[], int left, int right); int merge(int arr[], int temp[], int left, int mid, int right);

/* This function sorts the input array and returns the number of inversions in the array */ int mergeSort(int arr[], int array_size) { int *temp = (int *)malloc(sizeof(int)*array_size); return _mergeSort(arr, temp, 0, array_size - 1); } /* An auxiliary recursive function that sorts the input array and returns the number of inversions in the array. */ int _mergeSort(int arr[], int temp[], int left, int right) { int mid, inv_count = 0; if (right > left) { /* Divide the array into two parts and call _mergeSortAndCountInv() for each of the parts */ mid = (right + left)/2; /* Inversion count will be sum of inversions in left-part, rightpart and number of inversions in merging */ inv_count = _mergeSort(arr, temp, left, mid); inv_count += _mergeSort(arr, temp, mid+1, right); /*Merge the two parts*/ inv_count += merge(arr, temp, left, mid+1, right);

} return inv_count;

/* This funt merges two sorted arrays and returns inversion count in the arrays.*/ int merge(int arr[], int temp[], int left, int mid, int right) { int i, j, k; int inv_count = 0; i = left; /* i is index for j = mid; /* i is index for k = left; /* i is index for while ((i <= mid - 1) && (j { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; left subarray*/ right subarray*/ resultant merged subarray*/ <= right))

/*this is tricky -- see above explanation/diagram for merge()*/ inv_count = inv_count + (mid - i); } }

/* Copy the remaining elements of left subarray (if there are any) to temp*/ while (i <= mid - 1) temp[k++] = arr[i++]; /* Copy the remaining elements of right subarray (if there are any) to temp*/ while (j <= right) temp[k++] = arr[j++]; /*Copy back the merged elements to original array*/ for (i=left; i <= right; i++) arr[i] = temp[i]; return inv_count; }

Note that above code modifies (or sorts) the input array. If we want to count only inversions then we need to create a copy of original array and call mergeSort() on copy. Time Complexity: O(nlogn) Algorithmic Paradigm: Divide and Conquer

Sort elements by frequency


Question: Print the elements of an array in the decreasing frequency if 2 numbers have same frequency then print the one which came 1st E.g. 2 5 2 8 5 6 8 8 output: 8 8 8 2 2 5 5 6. METHOD 1 (Use Sorting)
1) Use a sorting algorithm to sort the elements O(nlogn) 2) Scan the sorted array and construct a 2D array of element and count O(n). 3) Sort the 2D array according to count O(nlogn).

Example:
Input 2 5 2 8 5 6 8 8 After sorting we get 2 2 5 5 6 8 8 8 Now construct the 2D array as 2, 2 5, 2 6, 1 8, 3 Sort by count

8, 2, 5, 6,

3 2 2 1

There is one issue with above approach (thanks to ankit for pointing this out). If we modify the input to 5 2 2 8 5 6 8 8, then we should get 8 8 8 5 5 2 2 6 and not 8 8 8 2 2 5 5 6 as will be the case. To handle this, we should use indexes in step 3, if two counts are same then we should first process(or print) the element with lower index. In step 1, we should store the indexes instead of elements.
Input 5 2 2 8 5 6 8 8

After sorting we get Element 2 2 5 5 6 8 8 8 Index 1 2 0 4 5 3 6 7 Now construct the 2D array as Index, Count 1, 2 0, 2 5, 1 3, 3 Sort by count (consider indexes in case of tie) 3, 3 0, 2 1, 2 5, 1 Print the elements using indexes in the above 2D array.

METHOD 2(Use BST and Sorting) 1. Insert elements in BST one by one and if an element is already present then increment the count of the node. Node of the Binary Search Tree (used in this approach) will be as follows.
struct tree { int element; int first_index /*To handle ties in counts*/ int count; }BST;

2.Store the first indexes and corresponding counts of BST in a 2D array. 3 Sort the 2D array according to counts (and use indexes in case of tie). Time Complexity: O(nlogn) if a Self Balancing Binary Search Tree is used.

METHOD 3(Use Hashing and Sorting) Using a hashing mechanism, we can store the elements (also first index) and their counts in a hash. Finally, sort the hash elements according to their counts.

These are just our thoughts about solving the problem and may not be the optimal way of solving. We are open for better solutions.

Write a recursive function to print reverse of a Linked List


Note that the question is only about printing the reverse. To reverse the list itself see this Algorithm
printReverse(head) 1. call print reverse for hed->next 2. print head->data

Implementation:
/* Link list node */ struct node { int data; struct node* next; }; /* Function to reverse the linked list */ void printReverse(struct node* head) { if(head == NULL) return; printReverse(head->next); printf("%d ", head->data);

Time Complexity: O(n)

Babylonian method for square root

Algorithm: This method can be derived from (but predates) NewtonRaphson method.
1 Start with an arbitrary positive start value x (the closer to the root, the better). 2 Initialize y = 1. 3. Do following until desired approximation is achieved. a) Get the next approximation for root using average of x and y b) Set y = n/x

Implementation:
/*Returns the square root */ float squareRoot(float n) { /*We are using n itself This can definitely be float x = n; float y = 1; float e = 0.000001; /* e while(x - y > e) { x = (x + y)/2; y = n/x; } return x; } of n. Note that the function

as initial approximation improved */ decides the accuracy level*/

If we are sure that n is a perfect square then we can use following method. The method can go in infinite loop for non-perfect-square numbers. For example for 3 the loop will never terminate.
/*Returns the square root of n. Note that the function will not work for numbers which are not perfect squares*/ unsigned int squareRoot(int n) { int x = n; int y = 1; while(x > y) { x = (x + y)/2; y = n/x; } return x; }

Maximum sum such that no two elements are adjacent


Question: Given an array all of whose elements are positive numbers, find the maximum sum of a subsequence with the constraint that no 2 numbers in the sequence should be

adjacent in the array. So 3 2 7 10 should return 13 (sum of 3 and 10) or 3 2 5 10 7 should return 15 (sum of 3, 5 and 7).Answer the question in most efficient way. Algorithm: Loop for all elements in arr[] and maintain two sums incl and excl where incl = Max sum including the previous element and excl = Max sum excluding the previous element. Max sum excluding the current element will be max(incl, excl) and max sum including the current element will be excl + current element (Note that only excl is considered because elements cannot be adjacent). At the end of the loop return max of incl and excl. Example:
arr[] = {5, inc = 5 exc = 0 For i = 1 (current element is 5) incl = (excl + arr[i]) = 5 excl = max(5, 0) = 5 For i = 2 (current element is 10) incl = (excl + arr[i]) = 15 excl = max(5, 5) = 5 For i = 3 (current element is 40) incl = (excl + arr[i]) = 45 excl = max(5, 15) = 15 For i = 4 (current element is 50) incl = (excl + arr[i]) = 65 excl = max(45, 15) = 45 For i = 5 (current element is 35) incl = (excl + arr[i]) = 80 excl = max(5, 15) = 65 And 35 is the last element. So, answer is max(incl, excl) = 80 5, 10, 40, 50, 35}

Implementation:
/*Function to return max sum such that no two elements are adjacent */ int FindMaxSum(int arr[], int n) { int incl = arr[0]; int excl = 0; int excl_new;

int i; for (i = 1; i < n; i++) { /* current max excluding i */ excl_new = (incl > excl)? incl: excl; /* current max including i */ incl = excl + arr[i]; excl = excl_new; } /* return max of incl and excl */ return ((incl > excl)? incl : excl);

Time Complexity: O(n)

Reversal algorithm for array rotation


Write a function rotate(arr[], d, n) that rotates arr[] of size n by d elements.

Rotation of the above array by 2 will make array

Method 4(The Reversal Algorithm) Please read this for first three methods of array rotation. Algorithm:
rotate(arr[], d, reverse(arr[], reverse(arr[], reverse(arr[], n) 1, d) ; d + 1, n); l, n);

Let AB are the two parts of the input array where A = arr[0..d-1] and B = arr[d..n-1]. The idea of the algorithm is:

Reverse A to get ArB. /* Ar is reverse of A */ Reverse B to get ArBr. /* Br is reverse of B */ Reverse all to get (ArBr) r = BA. For arr[] = [1, 2, 3, 4, 5, 6, 7], d =2 and n = 7 A = [1, 2] and B = [3, 4, 5, 6, 7] Reverse A, we get ArB = [2, 1, 3, 4, 5, 6, 7] Reverse B, we get ArBr = [2, 1, 7, 6, 5, 4, 3] Reverse all, we get (ArBr)r = [3, 4, 5, 6, 7, 1, 2] Implementation:
/* Function to left rotate arr[] of size n by d */ void leftRotate(int arr[], int d, int n) { rvereseArray(arr, 0, d-1); rvereseArray(arr, d, n-1); rvereseArray(arr, 0, n-1); } /*Function to reverse arr[] from index start to end*/ void rvereseArray(int arr[], int start, int end) { int i; int temp; while(start < end) { temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; start++; end--; } }

Time Complexity: O(n)

Compute the minimum or maximum of two integers without branching


On some rare machines where branching is expensive, the below obvious approach to find minimum can be slow as it uses branching.
/* The obvious approach to find minimum (involves branching) */ int min(int x, int y) { return (x < y) ? x : y }

Below are the methods to get minimum(or maximum) without using branching. Typically, the obvious approach is best, though. Method 1(Use XOR and comparison operator) Minimum of x and y will be
y ^ ((x ^ y) & -(x < y))

It works because if x < y, then -(x < y) will be all ones, so r = y ^ (x ^ y) & ~0 = y ^ x ^ y = x. Otherwise, if x >= y, then -(x < y) will be all zeros, so r = y ^ ((x ^ y) & 0) = y. On some machines, evaluating (x < y) as 0 or 1 requires a branch instruction, so there may be no advantage. To find the maximum, use
x ^ ((x ^ y) & -(x < y));

/*Function to find minimum of x and y*/ int min(int x, int y) { return y ^ ((x ^ y) & -(x < y)); } /*Function to find maximum of x and y*/ int max(int x, int y) { return x ^ ((x ^ y) & -(x < y)); }

Method 2(Use subtraction and shift) If we know that


INT_MIN <= (x - y) <= INT_MAX

, then we can use the following, which are faster because (x - y) only needs to be evaluated once. Minimum of x and y will be
y + ((x - y) & ((x - y) >>(sizeof(int) * CHAR_BIT - 1)))

This method shifts the subtraction of x and y by 31 (if size of integer is 32). If (x-y) is smaller than 0, then (x -y)>>31 will be 1. If (x-y) is greater than or equal to 0, then (x -y)>>31 will be 0.

So if x >= y, we get minimum as y + (x-y)&0 which is y. If x < y, we get minimum as y + (x-y)&1 which is x. Similarly, to find the maximum use
x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)))

#include<stdio.h> #define CHAR_BIT 8 /*Function to find minimum of x and y*/ int min(int x, int y) { return y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); } /*Function to find maximum of x and y*/ int max(int x, int y) { return x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); } /* Driver program to test above functions */ int main() { int x = 15; int y = 6; printf("Minimum of %d and %d is ", x, y); printf("%d", min(x, y)); printf("\nMaximum of %d and %d is ", x, y); printf("%d", max(x, y)); getchar(); }

Note that the 1989 ANSI C specification doesn't specify the result of signed right-shift, so above method is not portable. If exceptions are thrown on overflows, then the values of x and y should be unsigned or cast to unsigned for the subtractions to avoid unnecessarily throwing an exception, however the right-shift needs a signed operand to produce all one bits when negative, so cast to signed there.

Write a program to reverse an array


Iterative way: 1) Initialize start and end indexes. start = 0, end = n-1 2) In a loop, swap arr[start] with arr[end] and change start and end as follows. start = start +1; end = end 1

Time Complexity: O(n) Recursive Way: 1) Initialize start and end indexes start = 0, end = n-1 2) Swap arr[start] with arr[end] 3) Recursively call reverse for rest of the array.
/* Function to reverse arr[] from start to end*/ void rvereseArray(int arr[], int start, int end) { int temp; if(start >= end) return; temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; rvereseArray(arr, start+1, end-1); }

Time Complexity: O(n)

Find the two non-repeating elements in an array of repeating elements


Given an array in which all numbers except two are repeated once. (i.e. we have 2n+2 numbers and n numbers are occurring twice and remaining two have occurred once). Find those two numbers in the most efficient way. Method 1(Use Sorting) First sort all the elements. In the sorted array, by comparing adjacent elements we can easily get the non-repeating elements. Time complexity of this method is O(nLogn) Method 2(Use XOR) Let x and y be the non-repeating elements we are looking for and arr[] be the input array. First calculate the XOR of all the array elements.
xor = arr[0]^arr[1]^arr[2].....arr[n-1]

All the bits that are set in xor will be set in one non-repeating element (x or y) and not in other. So if we take any set bit of xor and divide the elements of the array in two sets one set of elements with same bit set and other set with same bit not set. By doing so, we will get x in one set and y in another set. Now if we do XOR of all the elements in first

set, we will get first non-repeating element, and by doing same in other set we will get the second non-repeating element.
Let us see an example. arr[] = {2, 4, 7, 9, 2, 4} 1) Get the XOR of all the elements. xor = 2^4^7^9^2^4 = 14 (1110) 2) Get a number which has only one set bit of the xor. Since we can easily get the rightmost set bit, let us use it. set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010 Now set_bit_no will have only set as rightmost set bit of xor. 3) Now divide the elements in two sets and do xor of elements in each set, and we get the non-repeating elements 7 and 9. Please see implementation for this step.

Implementation:
/* This finction sets the values of *x and *y to nonr-epeating elements in an array arr[] of size n*/ void get2NonRepeatingNos(int arr[], int n, int *x, int *y) { int xor = arr[0]; /* Will hold xor of all elements */ int set_bit_no; /* Will have only single set bit of xor */ int i; *x = 0; *y = 0; /* Get the xor of all elements */ for(i = 1; i < n; i++) xor ^= arr[i]; /* Get the rightmost set bit in set_bit_no */ set_bit_no = xor & ~(xor-1); /* Now divide elements in two sets by comparing rightmost set bit of xor with bit at same position in each element. */ for(i = 0; i < n; i++) { if(arr[i] & set_bit_no) *x = *x ^ arr[i]; /*XOR of first set */ else *y = *y ^ arr[i]; /*XOR of second set*/ } }

Time Complexity: O(n) Auxiliary Space: O(1)

Write a function to get the intersection point of two Linked Lists.

There are two singly linked lists in a system. By some programming error the end node of one of the linked list got linked into the second list, forming a inverted Y shaped list. Write a program to get the point where two linked list merge.

Above diagram shows an example with two linked list having 15 as intersection point. Method 1(Simply use two loops) Use 2 nested for loops. Outer loop will be for each node of the 1st list and inner loop will be for 2nd list. In the inner loop, check if any of nodes of 2nd list is same as the current node of first linked list. Time complexity of this method will be O(mn) where m and n are the number of nodes in two lists. Method 2 (Mark Visited Nodes) This solution requires modifications to basic linked list data structure. Have a visited flag with each node. Traverse the first linked list and keep marking visited nodes. Now traverse second linked list, If you see a visited node again then there is an intersection point, return the intersecting node. This solution works in O(m+n) but requires additional information with each node. A variation of this solution that doesnt require modification to basic data structure can be implemented using hash. Traverse the first linked list and store the addresses of visited nodes in a hash. Now traverse the second linked list and if you see an address that already exists in hash then return the intersecting node. Method 3(Using difference of node counts) 1) Get count of the nodes in first list, let count be c1. 2) Get count of the nodes in second list, let count be c2. 3) Get the difference of counts d = abs(c1 c2) 4) Now traverse the bigger list from the first node till d nodes so that from here onwards both the lists have equal no of nodes. 5) Then we can traverse both the lists in parallel till we come across a common node. (Note that getting a common node is done by comparing the address of the nodes)

/* Link list node */ struct node { int data; struct node* next; }; /* Function to get the counts of node in a linked list */ int getCount(struct node* head); /* function to get the intersection point of two linked lists head1 and head2 where head1 has d more nodes than head2 */ int _getIntesectionNode(int d, struct node* head1, struct node* head2); /* function to get the intersection point of two linked lists head1 and head2 */ int getIntesectionNode(struct node* head1, struct node* head2) { int c1 = getCount(head1); int c2 = getCount(head2); int d; if(c1 > c2) { d = c1 - c2; return _getIntesectionNode(d, head1, head2); } else { d = c2 - c1; return _getIntesectionNode(d, head2, head1); }

/* function to get the intersection point of two linked lists head1 and head2 where head1 has d more nodes than head2 */ int _getIntesectionNode(int d, struct node* head1, struct node* head2) { int i; struct node* current1 = head1; struct node* current2 = head2; for(i = 0; i < d; i++) { if(current1 == NULL) { return -1; } current1 = current1->next; } while(current1 != NULL && current2 != NULL) { if(current1 == current2) return current1->data;

current1= current1->next; current2= current2->next; } return -1; } /* Takes head pointer of the linked list and returns the count of nodes in the list */ int getCount(struct node* head) { struct node* current = head; int count = 0; while (current != NULL) { count++; current = current->next; } return count;

Time Complexity: O(m+n) Auxiliary Space: O(1) Method 4(Make circle in first list) 1. Traverse the first linked list(count the elements) and make a circular linked list. (Remember last node so that we can break the circle later on). 2. Now view the problem as find the loop in the second linked list. So the problem is solved. 3. Since we already know the length of the loop(size of first linked list) we can traverse those many number of nodes in second list, and then start another pointer from the beginning of second list. we have to traverse until they are equal, and that is the required intersection point. 4. remove the circle from the linked list. Time Complexity: O(m+n) Auxiliary Space: O(1) Method 5 (Reverse the first list and make equations)
1) Let X be the length of the first linked list until intersection point. Let Y be the length of the second linked list until the intersection point. Let Z be the length of the linked list from intersection point to End of the linked list including the intersection node. We Have X + Z = C1;

Y + Z = C2; 2) Reverse first linked list. 3) Traverse Second linked list. Let C3 be the length of second list - 1. Now we have X + Y = C3 We have 3 linear equations. By solving them, we get X = (C1 + C3 C2)/2; Y = (C2 + C3 C1)/2; Z = (C1 + C2 C3)/2; WE GOT THE INTERSECTION POINT. 4) Reverse first linked list.

Advantage: No Comparison of pointers. Disadvantage : Modifying linked list(Reversing list). Time complexity: O(m+n) Auxiliary Space: O(1) Method 6 (Store the first node and reverse the first list) This method is only to detect if there is an intersection point or not. Below algorithm will return 1 if there is an intersection else 0. (Thanks to Hari Prasad Perabattula for suggesting this)
1). Store the header node of list l1. 2). Reverse the first list l1. 3). Traverse the second list until reaches NULL. 4). Check if the node just before NULL is the same as the header in step (1). If it is then there is an intersection(return 1), otherwise not (return 0). 5).Reverse the list l1 to make it restore the original list.

Time complexity of this method is O(m+n) and used Auxiliary space is O(1)

Given a linked list which is sorted, how will you insert in sorted way
Algorithm: Let input linked list is sorted in increasing order.
1) If Linked list is empty then make the node as head and return it. 2) If value of the node to be inserted is smaller than value of head node then insert the node at start and make it head. 3) In a loop, find the appropriate node after which the input node (let 9) is to be inserted. To find the appropriate node start from head, keep moving until you reach a node GN (10 in the below diagram) who's value is greater than the input node. The node just before GN is the appropriate node (7).

4) Insert the node (9) after the appropriate node (7) found in step 3.

Initial Linked List

Linked List after insertion of 9

Implementation:
/* Program to insert in a sorted list */ /* Link list node */ struct node { int data; struct node* next; }; /* function to insert a new_node in a list. Note that this function expects a pointer to head_ref as this can modify the head of the input linked list (similar to push())*/ void sortedInsert(struct node** head_ref, struct node* new_node) { struct node* current; /* Special case for the head end */ if (*head_ref == NULL || (*head_ref)->data >= new_node->data) { new_node->next = *head_ref; *head_ref = new_node; } else { /* Locate the node before the point of insertion */ current = *head_ref; while (current->next!=NULL && current->next->data < new_node->data) { current = current->next; } new_node->next = current->next; current->next = new_node; } }

Given a string, find its first non-repeating character


Algorithm:

1) Scan the string from left to right and construct the count array. 2) Again, scan the string from left to right and check for count of each character, if you find an element who's count is 1, return it.

Example:
Input string: str = geeksforgeeks 1: Construct character count array from the input string. .... count['e'] = 4 count['f'] = 1 count['g'] = 2 count['k'] = 2 2: Get the first character who's count is 1 ('f').

Implementation:
#define NO_OF_CHARS 256 /* Returns an array of size 256 containg count of characters in the passed char array */ int *getCharCountArray(char *str) { int *count = (int *)calloc(sizeof(int), NO_OF_CHARS); int i; for (i = 0; *(str+i); i++) count[*(str+i)]++; return count; } /* The function returns index of first non-repeating character in a string. If all characters are repeating then reurns -1 */ int firstNonRepeating(char *str) { int *count = getCharCountArray(str); int index = -1, i; for (i = 0; *(str+i); i++) { if(count[*(str+i)] == 1) { index = i; break; } } return index; }

Time Complexity: O(n)

Count number of bits to be flipped to convert A to B


Question: You are given two numbers A and B. Write a program to count number of bits needed to be flipped to convert A to B. Solution:
1. Calculate XOR of A and B. a_xor_b = A ^ B 2. Count the set bits in the above calculated XOR result. countSetBits(a_xor_b)

XOR of two number will have set bits only at those places where A differs from B. Example:
A = 1001001 B = 0010101 a_xor_b = 1011100 No of bits need to flipped = set bit count in a_xor_b i.e. 4

Divide a string in N equal parts


Question: Write a program to print N equal parts of a given string. Solution: 1) Get the size of the string using string function strlen() (present in string.h) 2) Get size of a part.
part_size = string_length/n

3) Loop through the input string. In loop, if index becomes multiple of part_size then put a part separator(\n) Implementation:
/* Function to print n equal parts of str*/ void divideString(char *str, int n) { int str_size = strlen(str); int i; int part_size; /*Check if string can be divided in n equal parts */

if(str_size%n != 0) { printf("Invalid Input: String size is not divisible by n"); return; } /* Calculate the size of parts to find the division points*/ part_size = str_size/n; for(i = 0; i< str_size; i++) { if(i%part_size == 0) printf("\n"); /* newline separator for different parts */ printf("%c", str[i]); }

In above solution, we are simply printing the N equal parts of the string. If we want individual parts to be stored then we need to allocate part_size + 1 memory for all N parts (1 extra for string termination character \0), and store the addresses of the parts in an array of character pointers.

Merge an array of size n into another array of size m+n


Question: There are two sorted arrays. First one is of size m+n containing only m elements. Another one is of size n and contains n elements. Merge these two arrays into the first array of size m+n such that the output is sorted. Input: array with m+n elements (mPlusN[]).

NA => Value is not filled/available in array mPlusN[]. There should be n such array blocks. Input: array with n elements (N[]).

Output: N[] merged into mPlusN[] (Modified mPlusN[])

Algorithm:
Let first array be mPlusN[] and other array be N[] 1) Move m elements of mPlusN[] to end. 2) Start from nth element of mPlusN[] and 0th element of N[] and merge them into mPlusN[].

Implementation: ?
/* Assuming -1 is filled for the places where element is not available */ #define NA -1 /* Function to move m elements at the end of array mPlusN[] */ void moveToEnd(int mPlusN[], int size) { int i = 0, j = size - 1; for (i = size-1; i >= 0; i--) if(mPlusN[i] != NA) { mPlusN[j] = mPlusN[i]; j--; } } /* Merges array N[] of size n into array mPlusN[] of size m+n*/ int merge(int mPlusN[], int N[], int m, int n) { int i = n; /* Current index of i/p part of mPlusN[]*/ int j = 0; /* Current index of N[]*/ int k = 0; /* Current index of of output mPlusN[]*/ while(k <= (m+n)) { /* Take the element from mPlusN[] if a) its value is smaller and we have not reached end of it b) We have reached end of N[] */ if((i < (m+n) && mPlusN[i] <= N[j]) || ( j == n)) { mPlusN[k] = mPlusN[i]; k++; i++; } else { mPlusN[k] = N[j]; k++; j++; } } }

Time Complexity: O(m+n)

Find the node with minimum value in a Binary Search Tree


This is quite simple. Just traverse the node from root to left recursively until left is NULL. The node whose left is NULL is the node with minimum value.

For the above tree, we start with 20, then we move left 8, we keep on moving to left until we see NULL. Since left of 4 is NULL, 4 is the node with minimum value.
/* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node);

/* Give a binary search tree and a number, inserts a new node with the given number in the correct place in the tree. Returns the new root pointer which the caller should then use (the standard trick to avoid

using reference parameters). */ struct node* insert(struct node* node, int data) { /* 1. If the tree is empty, return a new, single node */ if (node == NULL) return(newNode(data)); else { /* 2. Otherwise, recur down the tree */ if (data <= node->data) node->left = insert(node->left, data); else node->right = insert(node->right, data); /* return the (unchanged) node pointer */ return node; } }

/* Given a non-empty binary search tree, return the minimum data value found in that tree. Note that the entire tree does not need to be searched. */ int minValue(struct node* node) { struct node* current = node; /* loop down to find the leftmost leaf */ while (current->left != NULL) { current = current->left; } return(current->data);

/* Driver program to test sameTree function*/ int main() { struct node* root = NULL; root = insert(root, 4); insert(root, 2); insert(root, 1); insert(root, 3); insert(root, 6); insert(root, 5); printf("\n Minimum value in BST is %d", minValue(root)); getchar(); return 0;

Time Complexity: O(n) Worst case happens for left skewed trees.

Copy a linked list with next and arbit pointer

August 24, 2009 Asked by Varun Bhatia. Question: You are given a Double Link List with one pointer of each node pointing to the next node just like in a single link list. The second pointer however CAN point to any node in the list and not just the previous node. Now write a program in O(n) time to duplicate this list. That is, write a program which will create a copy of this list. Let us call the second pointer as arbit pointer as it can point to any arbitrary node in the linked list. 1. Solution for Restricted Version of the Question: Let us first solve the restricted version of the original question. The restriction here is that a node will be pointed by only one arbit pointer in a linked list. In below diagram, we have obeyed the restriction.

Figure 1 Algorithm: 1) Create all nodes in copy linked list using next pointers. 2) Change next of original linked list to the corresponding node in copy linked list. 3) Change the arbit pointer of copy linked list to point corresponding node in original linked list. See below diagram after above three steps.

Figure 2 4) Now construct the arbit pointer in copy linked list as below and restore the next pointer of the original linked list.
copy_list_node->arbit = copy_list_node->arbit->arbit->next /* This can not be done if we remove the restriction*/ orig_list_node->next = orig_list_node->next->next->arbit

Time Complexity: O(n) Space Complexity: O(1) 2. Solution for the Original Question: If we remove the restriction given in above solution then we CANNOT restore the next pointer of the original linked in step 4 of above solution. We have to store the node and its next pointer mapping in original linked list. Below diagram doesnt obey the restriction as node 3 is pointed by arbit of 1 and 4.

Figure 3

Algorithm: 1) Create all nodes in copy linked list using next pointers. 3) Store the node and its next pointer mappings of original linked list. 3) Change next of original linked list to the corresponding node in copy linked list.

Figure 4 4) Change the arbit pointer of copy linked list to point corresponding node in original linked list. 5) Now construct the arbit pointer in copy linked list as below and restore the next pointer of the original linked list.
copy_list_node->arbit = copy_list_node->arbit->arbit->next

6) Restore the node and its next pointer of original linked list from the stored mappings(in step 2). Time Complexity: O(n) Space Complexity: O(n)

3. A Constant Space and O(n) Time Solution for the Original Question: Thanks to Saravanan Mani for providing this solution. This is the best solution among all three as it works in constant space and without any restriction on original linked list. 1) Create the copy of 1 and insert it between 1 & 2, create the copy of 2 and insert it between 2 & 3.. Continue in this fashion, add the copy of N to Nth node 2) Now copy the arbitrary link in this fashion
original->next->arbitrary = original->arbitrary->next; TWO NODES*/ /*TRAVERSE

This works because original->next is nothing but copy of original and Original>arbitrary->next is nothing but copy of arbitrary. 3) Now restore the original and copy linked lists in this fashion in a single loop.
original->next = original->next->next; copy->next = copy->next->next;

4) Make sure that last element of original->next is NULL. Time Complexity: O(n) Space Complexity: O(1)

Count set bits in an integer


August 19, 2009

Write an efficient program to count number of 1s in binary representation of an integer. 1. Simple Method Loop through all bits in an integer, check if a bit is set and if it is then increment the set bit count. See below program.
? /* Function to get no of set bits in binary representation of passed binary no. */ int countSetBits(unsigned int n) { unsigned int count = 0; while(n) { count += n & 1; n >>= 1; } return count; } /* Program to test function countSetBits */ int main() { int i = 9; printf("%d", countSetBits(i)); getchar(); return 0; }

Time Complexity: (-)(logn) (Theta of logn) 2. Brian Kernighans Algorithm: Subtraction of 1 from a number toggles all the bits (from right to left) till the rightmost

set bit(including the righmost set bit). So if we subtract a number by 1 and do bitwise & with itself (n & (n-1)), we unset the righmost set bit. If we do n & (n-1) in a loop and count the no of times loop executes we get the set bit count. Beauty of the this solution is number of times it loops is equal to the number of set bits in a given integer.
1 2 Initialize count: = 0 If integer n is not zero (a) Do bitwise & with (n-1) and assign the value back to n n: = n&(n-1) (b) Increment count by 1 (c) go to step 2 Else return count

Implementation of Brian Kernighans Algorithm:


? #include<stdio.h> /* Function to get no of set bits in binary representation of passed binary no. */ int countSetBits(int n) { unsigned int count = 0; while (n) { n &= (n-1) ; count++; } return count; } /* Program to test function countSetBits */ int main() { int i = 9; printf("%d", countSetBits(i)); getchar(); return 0; }

Example for Brian Kernighans Algorithm:


n = 9 (1001) count = 0 Since 9 > 0, subtract by 1 and do bitwise & with (9-1) n = 9&8 (1001 & 1000) n = 8 count = 1

Since 8 > 0, subtract by 1 and do bitwise & with (8-1) n = 8&7 (1000 & 0111) n = 0 count = 2 Since n = 0, return count which is 2 now.

Time Complexity: O(logn) 3. Using Lookup table: We can count bits in O(1) time using lookup table. Please see http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable for details.

Search an element in a sorted and pivoted array


August 15, 2009

Question: An element in a sorted array can be found in O(log n) time via binary search. But suppose I rotate the sorted array at some pivot unknown to you beforehand. So for instance, 1 2 3 4 5 might become 3 4 5 1 2. Now devise a way to find an element in the rotated array in O(log n) time.

Solution: Thanks to Ajay Mishra for initial solution. Algorithm: Find the pivot point, divide the array in two sub-arrays and call binary search. The main idea for finding pivot is for a sorted (in increasing order) and pivoted array, pivot element is the only only element for which next element to it is smaller than it. Using above criteria and binary search methodology we can get pivot element in O(logn) time
Input arr[] = {3, 4, 5, 1, 2} Element to Search = 1 1) Find out pivot point and divide the array in two sub-arrays. (pivot = 2) /*Index of 5*/ 2) Now call binary search for one of the two sub-arrays. (a) If element is greater than 0th element then search in left array (b) Else Search in right array (1 will go in else as 1 < 0th element(3))

3) If element is found in selected sub-array then return index Else return -1.

Implementation:
? /*Program to search an element in a sorted and pivoted array*/ #include <stdio.h> int findPivot(int[], int, int); int binarySearch(int[], int, int, int); /* Searches an element no in a pivoted sorted array arrp[] of size arr_size */ int pivotedBinarySearch(int arr[], int arr_size, int no) { int pivot = findPivot(arr, 0, arr_size-1); if(arr[pivot] == no) return pivot; if(arr[0] <= no) return binarySearch(arr, 0, pivot-1, no); else return binarySearch(arr, pivot+1, arr_size-1, no); } /* Function to get pivot. For array 3, 4, 5, 6, 1, 2 it will return 3 */ int findPivot(int arr[], int low, int high) { int mid = (low + high)/2; /*low + (high - low)/2;*/ if(arr[mid] > arr[mid + 1]) return mid; if(arr[low] > arr[mid]) return findPivot(arr, low, mid-1); else return findPivot(arr, mid + 1, high); } /* Standard Binary Search function*/ int binarySearch(int arr[], int low, int high, int no) { if(high >= low) { int mid = (low + high)/2; /*low + (high - low)/2;*/ if(no == arr[mid]) return mid; if(no > arr[mid]) return binarySearch(arr, (mid + 1), high, no); else return binarySearch(arr, low, (mid -1), no); } /*Return -1 if element is not found*/ return -1;

/* Driver program to check above functions */ int main() { int arr[10] = {3, 4, 5, 6, 7, 1, 2}; int n = 5; printf("Index of the element is %d", pivotedBinarySearch(arr, 7, 5)); getchar(); return 0; }

Time Complexity O(logn)

Function to check if a singly linked list is palindrome


August 13, 2009 Asked by Varun Bhatia.

METHOD 1 (By reversing the list)


1. 2. 3. 4. Get the middle of the linked list. Reverse the second half of the linked list. Compare the first half and second half. Construct the original linked list by reversing the second half again and attaching it back to the first half

Implementation: ?
/* Program to check if a linked list is palindrome */ #include<stdio.h> #include<stdlib.h> #define bool int /* Link list node */ struct node { char data; struct node* next; };

void reverse(struct node**); bool compareLists(struct node*, struct node *); /* Function to check if given linked list is palindrome or not */ bool isPalindrome(struct node *head) { struct node *slow_ptr = head; struct node *fast_ptr = head; struct node *second_half; struct node *prev_of_slow_ptr = head; char res; if(head!=NULL) { /* Get the middle of the list. Move slow_ptr by 1 and fast_ptrr by 2, slow_ptr will have the |_n/2_|th node */ while((fast_ptr->next)!=NULL && (fast_ptr->next->next)!=NULL) { fast_ptr = fast_ptr->next->next; /*We need previous of the slow_ptr for linked lists with odd elements */ prev_of_slow_ptr = slow_ptr; slow_ptr = slow_ptr->next; } /* Case where we have even no of elements */ if(fast_ptr->next != NULL) { second_half = slow_ptr->next; reverse(&second_half); slow_ptr->next = NULL; res = compareLists(head, second_half); /*construct the original list back*/ reverse(&second_half); slow_ptr->next = second_half;

/* Case where we have odd no. of elements. Neither first nor second list should have the middle element */ else { second_half = slow_ptr->next; prev_of_slow_ptr->next = NULL; reverse(&second_half); res = compareLists(head, second_half); /*construct the original list back*/ reverse(&second_half); prev_of_slow_ptr->next = slow_ptr; slow_ptr->next = second_half;

} return res; } } Note that this

/* Function to reverse the linked list function may change the head */ void reverse(struct node** head_ref) { struct node* prev = NULL; struct node* current = *head_ref; struct node* next; while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } *head_ref = prev; }

/* Function to check if two input lists have same data*/ int compareLists(struct node* head1, struct node *head2) { struct node* temp1 = head1; struct node* temp2 = head2; while(temp1 && temp2) { if(temp1->data == temp2->data) { temp1 = temp1->next; temp2 = temp2->next; } else return 0; } /* Both are empty reurn 1*/ if(temp1 == NULL && temp2 == NULL) return 1; /* Will reach here when one is NULL and other is not */ return 0; } /* Push a node to linked list. Note that this function changes the head */ void push(struct node** head_ref, char new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref); /* move the head to pochar to the new node */ (*head_ref) = new_node; } /* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL; push(&head, push(&head, push(&head, push(&head, 'p'); 'e'); 'e'); 'p');

/* p->e->e->p */ if(isPalindrome(head) == 1) printf("Linked list is Palindrome"); else printf("Linked list is not Palindrome"); getchar(); return 0;

Time Complexity O(n) Auxiliary Space: O(1)

METHOD 2 (Using Recursion) Thanks to Sharad Chandra for suggesting this approach. Use two pointers left and right. Move right and left using recursion and check for following in each recursive call. 1) Sub-list is palindrome. 2) Value at current left and right are matching. If both above conditions are true then return true.
? #define bool int #include<stdio.h> #include<stdlib.h> /* Link list node */ struct node

{ };

char data; struct node* next;

bool isPalindrome(struct node **left, struct node *right) { /* stop recursion here */ if (!right) return true; /* If sub-list is not palindrome then no need to check for current left and right, return false */ bool isp = isPalindrome(left, right->next); if (isp == false) return false; /* Check values at current left and right */ bool isp1 = (right->data == (*left)->data); /* Move left to next node */ *left = (*left)->next; /* save next pointer */ return isp1; } /* UTILITY FUNCTIONS */ /* Push a node to linked list. Note that this function changes the head */ void push(struct node** head_ref, char new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node)); /* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref); /* move the head to pochar to the new node */ (*head_ref) = new_node;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL; push(&head, push(&head, push(&head, push(&head, push(&head, 'r'); 'a'); 'd'); 'a'); 'r');

/* r->a->d->a->r*/ if(isPalindrome(&head, head) == 1) printf("Linked list is Palindrome"); else printf("Linked list is not Palindrome"); getchar(); return 0;

Time Complexity: O(n) Auxiliary Space: O(n) if Function Call Stack size is considered, otherwise O(1).

Lowest Common Ancestor in a Binary Search Tree.


August 9, 2009

Asked by Varun Bhatia Given the values of two nodes in a *binary search tree*, write a c program to find the lowest common ancestor. You may assume that both values already exist in the tree. The function prototype is as follows:
int FindLowestCommonAncestor(node* root, int value1, int value)

I/P : 4 and 14 O/P : 8 (Here the common ancestors of 4 and 14, are {8,20}. Of {8,20}, the lowest one is 8).

Here is the solution Algorithm: The main idea of the solution is While traversing Binary Search Tree from top to

bottom, the first node n we encounter with value between n1 and n2, i.e., n1 < n < n2 is the Lowest or Least Common Ancestor(LCA) of n1 and n2 (where n1 < n2). So just traverse the BST in pre-order, if you find a node with value in between n1 and n2 then n is the LCA, if it's value is greater than both n1 and n2 then our LCA lies on left side of the node, if it's value is smaller than both n1 and n2 then LCA lies on right side. Implementation:
? #include <stdio.h> #include <stdlib.h> /* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

struct node* newNode(int ); /* Function to find least comman ancestor of n1 and n2 */ int leastCommanAncestor(struct node* root, int n1, int n2) { /* If we have reached a leaf node then LCA doesn't exist If root->data is equal to any of the inputs then input is not valid. For example 20, 22 in the given figure */ if(root == NULL || root->data == n1 || root->data == n2) return -1; /* If any of the input nodes is child of the current node we have reached the LCA. For example, in the above figure if we want to calculate LCA of 12 and 14, recursion should terminate when we reach 8*/ if((root->right != NULL) && (root->right->data == n1 || root->right->data == n2)) return root->data; if((root->left != NULL) && (root->left->data == n1 || root->left->data == n2)) return root->data; if(root->data > n1 && root->data < n2) return root->data; if(root->data > n1 && root->data > n2) return leastCommanAncestor(root->left, n1, n2); if(root->data < n1 && root->data < n2) return leastCommanAncestor(root->right, n1, n2);

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) {

struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); } /* Driver program to int main() { struct node *root root->left root->right root->right->left root->right->right test mirror() */ = = = = = newNode(2); newNode(1); newNode(4); newNode(3); newNode(5);

/* Constructed binary search tree is 2 / \ 1 4 / \ 3 5 */ printf("\n The Least Common Ancestor is \n"); printf("%d", leastCommanAncestor(root, 3, 5)); getchar(); return 0; }

Note that above function assumes that n1 is smaller than n2. Time complexity: O(n)

Lowest Common Ancestor in a Binary Search Tree.


August 9, 2009

Asked by Varun Bhatia Given the values of two nodes in a *binary search tree*, write a c program to find the lowest common ancestor. You may assume that both values already exist in the tree. The function prototype is as follows:
int FindLowestCommonAncestor(node* root, int value1, int value)

I/P : 4 and 14 O/P : 8 (Here the common ancestors of 4 and 14, are {8,20}. Of {8,20}, the lowest one is 8).

Here is the solution Algorithm: The main idea of the solution is While traversing Binary Search Tree from top to bottom, the first node n we encounter with value between n1 and n2, i.e., n1 < n < n2 is the Lowest or Least Common Ancestor(LCA) of n1 and n2 (where n1 < n2). So just traverse the BST in pre-order, if you find a node with value in between n1 and n2 then n is the LCA, if it's value is greater than both n1 and n2 then our LCA lies on left side of the node, if it's value is smaller than both n1 and n2 then LCA lies on right side. Implementation:
? #include <stdio.h> #include <stdlib.h> /* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

struct node* newNode(int ); /* Function to find least comman ancestor of n1 and n2 */ int leastCommanAncestor(struct node* root, int n1, int n2) { /* If we have reached a leaf node then LCA doesn't exist If root->data is equal to any of the inputs then input is not valid. For example 20, 22 in the given figure */

if(root == NULL || root->data == n1 || root->data == n2) return -1; /* If any of the input nodes is child of the current node we have reached the LCA. For example, in the above figure if we want to calculate LCA of 12 and 14, recursion should terminate when we reach 8*/ if((root->right != NULL) && (root->right->data == n1 || root->right->data == n2)) return root->data; if((root->left != NULL) && (root->left->data == n1 || root->left->data == n2)) return root->data; if(root->data > n1 && root->data < n2) return root->data; if(root->data > n1 && root->data > n2) return leastCommanAncestor(root->left, n1, n2); if(root->data < n1 && root->data < n2) return leastCommanAncestor(root->right, n1, n2); } /* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; } return(node); test mirror() */ = = = = = newNode(2); newNode(1); newNode(4); newNode(3); newNode(5);

/* Driver program to int main() { struct node *root root->left root->right root->right->left root->right->right

/* Constructed binary search tree is 2 / \ 1 4 / \ 3 5 */ printf("\n The Least Common Ancestor is \n"); printf("%d", leastCommanAncestor(root, 3, 5)); getchar(); return 0;

Note that above function assumes that n1 is smaller than n2. Time complexity: O(n)

Lucky Numbers
August 6, 2009 Lucky numbers are subset of integers. Rather than going into much theory, let us see the process of arriving at lucky numbers, Take the set of integers 1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19, First, delete every second number, we get following reduced set. 1,3,5,7,9,11,13,15,17,19, Now, delete every third number, we get 1,3,7,9,13,15,19,.. Continue this process indefinitely Any number that does NOT get deleted due to above process is called lucky. Therefore, set of lucky numbers is 1,3,7,13,25, Now, given an integer n, write a function to say whether this number is lucky or not.
bool isLucky(int n) Algorithm: Before every iteration, if we calculate position of the given no, then in a given iteration, we can determine if the no will be deleted. Suppose calculated position for the given no. is P before some iteration, and each Ith no. is going to be removed in this iteration, if P < I then input no is lucky, if P is such that P%I == 0 (I is a divisor of P), then input no is not lucky.

Recursive Way:
? #include <stdio.h> #define bool int /* Returns 1 if n is a lucky no. ohterwise returns 0*/ bool isLucky(int n) { static int counter = 2; /*variable next_position is just for readability of the program we can remove it and use n only */

int next_position = n; if(counter > n) return 1; if(n%counter == 0) return 0; /*calculate next position of input no*/ next_position -= next_position/counter; counter++; return isLucky(next_position);

/*Driver function to test above function*/ int main() { int x = 5; if( isLucky(x) ) printf("%d is a lucky no.", x); else printf("%d is not a lucky no.", x); getchar(); }

Example: Lets us take an example of 19 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,17,18,19,20,21, 1,3,5,7,9,11,13,15,17,19,.. 1,3,7,9,13,15,19,. 1,3,7,13,15,19, 1,3,7,13,19, In next step every 6th no .in sequence will be deleted. 19 will not be deleted after this step because position of 19 is 5th after this step. Therefore, 19 is lucky. Lets see how above C code finds out:
Current function call isLucky(19 ) isLucky(10) isLucky(7) isLucky(6) Position after this call 10 7 6 5 Counter for next call 3 4 5 6 Next Call isLucky(10) isLucky(7) isLucky(6) isLucky(5)

When isLucky(6) is called, it returns 1 (because counter > n).


Arrays Articles Bit Magic C/C++ Puzzles GFacts

Linked Lists MCQ Misc Output Strings Trees

Write an Efficient C Program to Reverse Bits of a Number


August 2, 2009

Method1 Simple Loop through all the bits of an integer. If a bit at ith position is set in the i/p no. then set the bit at (NO_OF_BITS 1) i in o/p. Where NO_OF_BITS is number of bits present in the given number.
? /* Function to reverse bits of num */ unsigned int reverseBits(unsigned int num) { unsigned int NO_OF_BITS = sizeof(num) * 8; unsigned int reverse_num = 0, i, temp; for (i = 0; i < NO_OF_BITS; i++) { temp = (num & (1 << i)); if(temp) reverse_num |= (1 << ((NO_OF_BITS - 1) - i)); } } return reverse_num;

/* Driver function to test above function */ int main() { unsigned int x = 2; printf("%u", reverseBits(x)); getchar(); }

Above program can be optimized by removing the use of variable temp. See below the modified code.
? unsigned int reverseBits(unsigned int num) { unsigned int NO_OF_BITS = sizeof(num) * 8; unsigned int reverse_num = 0;

} }

int i; for (i = 0; i < NO_OF_BITS; i++) { if((num & (1 << i))) reverse_num |= 1 << ((NO_OF_BITS - 1) - i); return reverse_num;

Time Complexity: O(log n) Space Complexity: O(1) Method 2 Standard The idea is to keep putting set bits of the num in reverse_num until num becomes zero. After num becomes zero, shift the remaining bits of reverse_num. Let num is stored using 8 bits and num be 00000110. After the loop you will get reverse_num as 00000011. Now you need to left shift reverse_num 5 more times and you get the exact reverse 01100000.
? unsigned int reverseBits(unsigned int num) { unsigned int count = sizeof(num) * 8 - 1; unsigned int reverse_num = num; num >>= 1; while(num) { reverse_num <<= 1; reverse_num |= num & 1; num >>= 1; count--; } reverse_num <<= count; return reverse_num; } int main() { unsigned int x = 1; printf("%u", reverseBits(x)); getchar(); }

Time Complexity: O(log n) Space Complexity: O(1) Method 3 Lookup Table: We can reverse the bits of a number in O(1) if we know the size of the number. We can implement it using look up table. Go through the below link for details. You will find some more interesting bit related stuff there.

If you are given two traversal sequences, can you construct the binary tree? August 2, 2009 It depends on what traversals are given. If one of the traversal methods is Inorder then the tree can be constructed, otherwise not. Mirror Therefore, following combination can uniquely identify a tree. Inorder and Preorder. Inorder and Postorder. Inorder and Level-order. And following do not. Postorder and Preorder. Preorder and Level-order. Postorder and Level-order. For example, Preorder, Level-order and Postorder traversals are same for the trees given in above diagram. Preorder Traversal = AB Postorder Traversal = BA Level-Order Traversal = AB So, even if three of them (Pre, Post and Level) are given, the tree can not be constructed.

Write a C program to print all permutations of a given string


August 2, 2009

A permutation, also called an arrangement number or order, is a rearrangement of the elements of an ordered list S into a one-to-one correspondence with S itself. A string of length n has n! permutation. Source: Mathword(http://mathworld.wolfram.com/Permutation.html) Below are the permutations of string ABC. ABC, ACB, BAC, BCA, CAB, CBA

Here is a solution using backtracking.

? # include <stdio.h> # include <conio.h> /* Function to swap values at two pointers */ void swap (char *x, char *y) { char temp; temp = *x; *x = *y; *y = temp; } /* Function to print permutations of string This function takes three parameters: 1. String 2. Starting index of the string 3. Ending index of the string. */ void permute(char *a, int i, int n) { int j; if (i == n) printf("%s\n", a); else { for (j = i; j <= n; j++) { swap((a+i), (a+j)); permute(a, i+1, n); swap((a+i), (a+j)); //backtrack } }

} /* Driver program to test above functions */ int main() { char a[] = "ABC"; permute(a, 0, 2); getchar(); return 0; }

Algorithm Paradigm: Backtracking Time Complexity: O(n!)


Write a function that counts the number of times a given int occurs in a Linked List July 19, 2009 Here is a solution. Algorithm: 1. Initialize count as zero. 2. Loop through each element of linked list: a) If element data is equal to the passed number then increment the count. 3. Return count. Implementation: ? #include<stdio.h> #include<stdlib.h> /* Link list node */ struct node { int data; struct node* next; }; /* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node)); /* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) = new_node; } /* Counts the no. of occurences of a node (search_for) in a linked list (head)*/ int count(struct node* head, int search_for) { struct node* current = head; int count = 0; while (current != NULL) { if (current->data == search_for) count++; current = current->next; } return count; } /* Drier program to test count function*/ int main() { /* Start with the empty list */ struct node* head = NULL; /* Use push() to construct below list 1->2->1->3->1 */ push(&head, 1); push(&head, 3); push(&head, 1); push(&head, 2); push(&head, 1); /* Check the count function */ printf("count of 1 is %d", count(head, 1)); getchar(); } Time Complexity: O(n) Space Complexity: O(1) Ugly Numbers July 11, 2009 Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, shows the first 11 ugly numbers. By convention, 1 is included. Write a program to find and print the 150th ugly number. METHOD 1 (Simple) Thanks to Nedylko Draganov for suggesting this solution. Algorithm:

Loop for all positive integers until ugly number count is smaller than n, if an integer is ugly than increment ugly number count. To check if a number is ugly, divide the number by greatest divisible powers of 2, 3 and 5, if the number becomes 1 then it is an ugly number otherwise not. For example, let us see how to check for 300 is ugly or not. Greatest divisible power of 2 is 4, after dividing 300 by 4 we get 75. Greatest divisible power of 3 is 3, after dividing 75 by 3 we get 25. Greatest divisible power of 5 is 25, after dividing 25 by 25 we get 1. Since we get 1 finally, 300 is ugly number. Implementation: ? # include<stdio.h> # include<stdlib.h> /*This function divides a by greatest divisible power of b*/ int maxDivide(int a, int b) { while (a%b == 0) a = a/b; return a; } /* Function to check if a number is ugly or not */ int isUgly(int no) { no = maxDivide(no, 2); no = maxDivide(no, 3); no = maxDivide(no, 5); } return (no == 1)? 1 : 0;

/* Function to get the nth ugly number*/ int getNthUglyNo(int n) { int i = 1; int count = 1; /* ugly number count */ /*Check for all integers untill ugly count becomes n*/ while (n > count) { i++; if (isUgly(i)) count++; } return i; } /* Driver program to test above functions */ int main() {

unsigned no = getNthUglyNo(150); printf("150th ugly no. is %d ", no); getchar(); return 0;

This method is not time efficient as it checks for all integers until ugly number count becomes n, but space complexity of this method is O(1) METHOD 2 (Use Dynamic Programming) Here is a time efficient solution with O(n) extra space Algorithm: 1 Declare an array for ugly numbers: ugly[150] 2 Initialize first ugly no: ugly[0] = 1 3 Initialize three array index variables i2, i3, i5 to point to 1st element of the ugly array: i2 = i3 = i5 =0; 4 Initialize 3 choices for the next ugly no: next_mulitple_of_2 = ugly[i2]*2; next_mulitple_of_3 = ugly[i3]*3 next_mulitple_of_5 = ugly[i5]*5; 5 Now go in a loop to fill all ugly numbers till 150: For (i = 1; i < 150; i++ ) { /* These small steps are not optimized for good readability. Will optimize them in C program */ next_ugly_no = Min(next_mulitple_of_2, next_mulitple_of_3, next_mulitple_of_5); if (next_ugly_no == next_mulitple_of_2) { i2 = i2 + 1; next_mulitple_of_2 = ugly[i2]*2; } if (next_ugly_no == next_mulitple_of_3) { i3 = i3 + 1; next_mulitple_of_3 = ugly[i3]*3; } if (next_ugly_no == next_mulitple_of_5) { i5 = i5 + 1; next_mulitple_of_5 = ugly[i5]*5; } ugly[i] = next_ugly_no }/* end of for loop */ 6.return next_ugly_no Example: Let us see how it works

initialize ugly[] = | 1 | i2 = i3 = i5 = 0; First iteration ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(2, 3, 5) =2 ugly[] = | 1 | 2 | i2 = 1, i3 = i5 = 0 (i2 got incremented ) Second iteration ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(4, 3, 5) =3 ugly[] = | 1 | 2 | 3 | i2 = 1, i3 = 1, i5 = 0 (i3 got incremented ) Third iteration ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(4, 6, 5) =4 ugly[] = | 1 | 2 | 3 | 4 | i2 = 2, i3 = 1, i5 = 0 (i2 got incremented ) Fourth iteration ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(6, 6, 5) =5 ugly[] = | 1 | 2 | 3 | 4 | 5 | i2 = 2, i3 = 1, i5 = 1 (i5 got incremented ) Fifth iteration ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(6, 6, 10) =6 ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 | i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented ) Will continue same way till I < 150 Program: ? # include<stdio.h> # include<stdlib.h> # define bool int /* Function to find minimum of 3 numbers */ unsigned min(unsigned , unsigned , unsigned ); /* Function to get the nth ugly number*/ unsigned getNthUglyNo(unsigned n) { unsigned *ugly = (unsigned *)(malloc (sizeof(unsigned)*n));

unsigned i2 = 0, i3 = 0, i5 = 0; unsigned i; unsigned next_multiple_of_2 = 2; unsigned next_multiple_of_3 = 3; unsigned next_multiple_of_5 = 5; unsigned next_ugly_no = 1; *(ugly+0) = 1; for(i=1; i<n; i++) { next_ugly_no = min(next_multiple_of_2, next_multiple_of_3, next_multiple_of_5); *(ugly+i) = next_ugly_no; if(next_ugly_no == next_multiple_of_2) { i2 = i2+1; next_multiple_of_2 = *(ugly+i2)*2; } if(next_ugly_no == next_multiple_of_3) { i3 = i3+1; next_multiple_of_3 = *(ugly+i3)*3; } if(next_ugly_no == next_multiple_of_5) { i5 = i5+1; next_multiple_of_5 = *(ugly+i5)*5; } } /*End of for loop (i=1; i<n; i++) */ return next_ugly_no; } /* Function to find minimum of 3 numbers */ unsigned min(unsigned a, unsigned b, unsigned c) { if(a <= b) { if(a <= c) return a; else return c; } if(b <= c) return b; else return c; } /* Driver program to test above functions */ int main() { unsigned no = getNthUglyNo(150); printf("%dth ugly no. is %d ", 150, no); getchar();

return 0; } Algorithmic Paradigm: Dynamic Programming Time Complexity: O(n) Storage Complexity: O(n) Little and Big Endian Mystery July 16, 2009 What are these? Little and big endian are two ways of storing multibyte data-types ( int, float, etc). In little endian machines, last byte of binary representation of the multibyte data-type is stored first. On the other hand, in big endian machines, first byte of binary representation of the multibyte data-type is stored last. Suppose integer is stored as 4 bytes (For those who are using DOS based compilers such as C++ 3.0 , integer is 2 bytes) then a variable x with value 001234567 will be stored as following. Memory representation of integer ox01234567 inside Big and little endian machines How to see memory representation of multibyte data types on your machine? Here is a sample C code that shows the byte representation of int, float and pointer. ? #include <stdio.h> /* function to show bytes in memory, from location start to start+n*/ void show_mem_rep(char *start, int n) { int i; for (i = 0; i < n; i++) printf(" %.2x", start[i]); printf("\n"); } /*Main function to call above function for 0x01234567*/ int main() { int i = 0x01234567; show_mem_rep((char *)&i, sizeof(i)); getchar(); return 0; } When above program is run on little endian machine, gives 67 45 23 01 as output , while if it is run on endian machine, gives 01 23 45 67 as output. Is there a quick way to determine endianness of your machine? There are n no. of ways for determining endianness of your machine. Here is one quick way of doing the same. ? #include <stdio.h> int main() { unsigned int i = 1;

char *c = (char*)&i; if (*c) printf("Little endian"); else printf("Big endian"); getchar(); return 0; } In the above program, a character pointer c is pointing to an integer i. Since size of character is 1 byte when the character pointer is de-referenced it will contain only first byte of integer. If machine is little endian then *c will be 1 (because last byte is stored first) and if machine is big endian then *c will be 0. Does endianness matter for programmers? Most of the times compiler takes care of endianness, however, endianness becomes an issue in following cases. It matters in network programming: Suppose you write integers to file on a little endian machine and you transfer this file to a big endian machine. Unless there is little andian to big endian transformation, big endian machine will read the file in reverse order. You can find such a practical example here. Standard byte order for networks is big endian, also known as network byte order. Before transferring data on network, data is first converted to network byte order (big endian). Sometimes it matters when you are using type casting, below program is an example. ? #include <stdio.h> int main() { unsigned char arr[2] = {0x01, 0x00}; unsigned short int x = *(unsigned short int *) arr; printf("%d", x); getchar(); return 0; } In the above program, a char array is typecasted to an unsigned short integer type. When I run above program on little endian machine, I get 1 as output, while if I run it on a big endian machine I get 256. To make programs endianness independent, above programming style should be avoided. What are bi-endians? Bi-endian processors can run in both modes little and big endian. What are the examples of little, big endian and bi-endian machines ? Intel based processors are little endians. ARM processors were little endians. Current generation ARM processors are bi-endian. Motorola 68K processors are big endians. PowerPC (by Motorola) and SPARK (by Sun) processors were big endian. Current version of these processors are bi-endians. Does endianness effects file formats?

File formats which have 1 byte as a basic unit are independent of endianness e..g., ASCII files . Other file formats use some fixed endianness forrmat e.g, JPEG files are stored in big endian format. Which one is better little endian or big endian The term little and big endian came from Gullivers Travels by Jonathan Swift. Two groups could not agree by which end a egg should be opened -a-the little or the big. Just like the egg issue, there is no technological reason to choose one byte ordering convention over the other, hence the arguments degenerate into bickering about sociopolitical issues. As long as one of the conventions is selected and adhered to consistently, the choice is arbitrary. Arrays Articles Bit Magic C/C++ Puzzles GFacts Linked Lists MCQ Misc Output Strings Trees Write a C program to Calculate Size of a tree June 23, 2009 Size of a tree is the number of elements present in the tree. Size of the below tree is 5. Example Tree Example Tree Size() function recursively calculates the size of a tree. It works as follows: Size of a tree = Size of left subtree + 1 + Size of right subtree Algorithm: size(tree) 1. If tree is empty then return 0 2. Else (a) Get the size of left subtree recursively i.e., call size( tree->left-subtree) (a) Get the size of right subtree recursively i.e., call size( tree->right-subtree) (c) Calculate size of the tree as following: tree_size = size(left-subtree) + size(rightsubtree) + 1 (d) Return tree_size ? #include <stdio.h> #include <stdlib.h> /* A binary tree node has data, pointer to left child

and a pointer to right child */ struct node { int data; struct node* left; struct node* right; }; /* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; } /* Computes the number of nodes in a tree. */ int size(struct node* node) { if (node==NULL) return 0; else return(size(node->left) + 1 + size(node->right)); } /* Driver program to test size function*/ int main() { struct node *root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); printf("Size of the tree is %d", size(root)); getchar(); return 0; } Time & Space Complexities: Since this program is similar to traversal of tree, time and space complexities will be same as Tree traversal (Please see our Tree Traversal post for details) Print reverse of a string using recursion June 19, 2009 Write a recursive C function to print reverse of a given string. Program: ? # include <stdio.h> return(node);

/* Function to print reverse of the passed string */ void reverse(char *str) { if(*str) { reverse(str+1); printf("%c", *str); } } /* Driver program to test above function */ int main() { char a[] = "Geeks for Geeks"; reverse(a); getchar(); return 0; } Explanation: Recursive function (reverse) takes string pointer (str) as input and calls itself with next location to passed pointer (str+1). Recursion continues this way, when pointer reaches \0, all functions accumulated in stack print char at passed location (str) and return one by one. Time Complexity: O(n) Find the Number Occurring Odd Number of Times June 22, 2009 Given an array of positive integers. All numbers occur even number of times except one number which occurs odd number of times. Find the number in O(n) time & constant space. Example: I/P = [1, 2, 3, 2, 3, 1, 3] O/P = 3 Algorithm: Do bitwise XOR of all the elements. Finally we get the number which has odd occurrences. Program: ? #include <stdio.h> int getOddOccurrence(int ar[], int ar_size) { int i; int res = 0; for(i=0; i < ar_size; i++) res = res ^ ar[i]; } return res;

/* Diver function to test above function */ int main() { int ar[] = {2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2}; printf("%d", getOddOccurrence(ar, 13)); getchar(); } Time Complexity: O(n) Largest Sum Contiguous Subarray June 22, 2009 Write an efficient C program to find the sum of contiguous subarray within a one-dimensional array of numbers which has the largest sum. Kadanes Algorithm: Initialize: max_so_far = 0 max_ending_here = 0 Loop for each element of the array (a) max_ending_here = max_ending_here + a[i] (b) if(max_ending_here < 0) max_ending_here = 0 (c) if(max_so_far < max_ending_here) max_so_far = max_ending_here return max_so_far Explanation: Simple idea of the Kadane's algorithm is to look for all positive contiguous segments of the array (max_ending_here is used for this). And keep track of maximum sum contiguous segment among all positive segments (max_so_far is used for this). Each time we get a positive sum compare it with max_so_far and update max_so_far if it is greater than max_so_far Lets take the example: {-2, -3, 4, -1, -2, 1, 5, -3} max_so_far = max_ending_here = 0 for i=0, a[0] = -2 max_ending_here = max_ending_here + (-2) Set max_ending_here = 0 because max_ending_here < 0 for i=1, a[1] = -3 max_ending_here = max_ending_here + (-3) Set max_ending_here = 0 because max_ending_here < 0 for i=2, a[2] = 4 max_ending_here = max_ending_here + (4) max_ending_here = 4

max_so_far is updated to 4 because max_ending_here greater than max_so_far which was 0 till now for i=3, a[3] = -1 max_ending_here = max_ending_here + (-1) max_ending_here = 3 for i=4, a[4] = -2 max_ending_here = max_ending_here + (-2) max_ending_here = 1 for i=5, a[5] = 1 max_ending_here = max_ending_here + (1) max_ending_here = 2 for i=6, a[6] = 5 max_ending_here = max_ending_here + (5) max_ending_here = 7 max_so_far is updated to 7 because max_ending_here is greater than max_so_far for i=7, a[7] = -3 max_ending_here = max_ending_here + (-3) max_ending_here = 4 Program: ? #include<stdio.h> int maxSubArraySum(int a[], int size) { int max_so_far = 0, max_ending_here = 0; int i; for(i = 0; i < size; i++) { max_ending_here = max_ending_here + a[i]; if(max_ending_here < 0) max_ending_here = 0; if(max_so_far < max_ending_here) max_so_far = max_ending_here; } return max_so_far; } /*Driver program to test maxSubArraySum*/ int main() { int a[] = {-2, -3, 4, -1, -2, 1, 5, -3}; int max_sum = maxSubArraySum(a, 8); printf("Maximum contiguous sum is %d\n", max_sum); getchar(); return 0; } Notes: Algorithm doesn't work for all negative numbers. It simply returns 0 if all numbers are negative. For handling this we can add an extra phase before actual implementation. The phase will look

if all numbers are negative, if they are it will return maximum of them (or smallest in terms of absolute value). There may be other ways to handle it though. Above program can be optimized further, if we compare max_so_far with max_ending_here only if max_ending_here is greater than 0. ? int maxSubArraySum(int a[], int size) { int max_so_far = 0, max_ending_here = 0; int i; for(i = 0; i < size; i++) { max_ending_here = max_ending_here + a[i]; if(max_ending_here < 0) max_ending_here = 0; /* Do not compare for all elements. Compare only when max_ending_here > 0 */ else if (max_so_far < max_ending_here) max_so_far = max_ending_here;

} Time Complexity: O(n) Algorithmic Paradigm: Dynamic Programming Now try below question Given an array of integers (possibly some of the elements negative), write a C program to find out the *maximum product* possible by adding 'n' consecutive integers in the array, n <= ARRAY_SIZE. Also give where in the array this sequence of n integers starts. Arrays Articles Bit Magic C/C++ Puzzles GFacts Linked Lists MCQ Misc Output Strings Trees Find the Missing Number June 22, 2009 You are given a list of n-1 integers and these integers are in the range of 1 to n. There are no duplicates in list. One of the integers is missing in the list. Write an efficient code to find the missing integer. Example: I/P [1, 2, 4, ,6, 3, 7, 8] O/P 5

} return max_so_far;

METHOD 1(Use sum formula) Algorithm: 1. Get the sum of numbers total = n*(n+1)/2 2 Subtract all the numbers from sum and you will get the missing number. Program: ? #include<stdio.h> /* getMissingNo takes array and size of array as arguments*/ int getMissingNo (int a[], int n) { int i, total; total = (n+1)*(n+2)/2; for ( i = 0; i< n; i++) total -= a[i]; return total; } /*program to test above function */ int main() { int a[] = {1,2,4,5,6}; int miss = getMissingNo(a,5); printf("%d", miss); getchar(); } Time Complexity: O(n)

METHOD 2(Use XOR) 1) XOR all the array elements, let the result of XOR be X1. 2) XOR all numbers from 1 to n, let XOR be X2. 3) XOR of X1 and X2 gives the missing number. ? #include<stdio.h> /* getMissingNo takes array and size of array as arguments*/ int getMissingNo(int a[], int n) { int i; int x1 = a[0]; /* For xor of all the elemets in arary */ int x2 = 1; /* For xor of all the elemets from 1 to n+1 */ for (i = 1; i< n; i++) x1 = x1^a[i];

for ( i = 2; i <= n+1; i++) x2 = x2^i; return (x1^x2); } /*program to test above function */ int main() { int a[] = {1, 2, 4, 5, 6}; int miss = getMissingNo(a, 5); printf("%d", miss); getchar(); } Time Complexity: O(n) In method 1, if the sum of the numbers goes beyond maximum allowed integer, then there can be integer overflow and we may not get correct answer. Method 2 has no such problems. ower Set June 22, 2009 Power Set Power set P(S) of a set S is the set of all subsets of S. For example S = {a, b, c} then P(s) = {{}, {a}, {b}, {c}, {a,b}, {a, c}, {b, c}, {a, b, c}}. If S has n elements in it then P(s) will have 2^n elements Algorithm: Input: Set[], set_size 1. Get the size of power set powet_set_size = pow(2, set_size) 2 Loop for counter from 0 to pow_set_size (a) Loop for i = 0 to set_size (i) If ith bit in counter is set Print ith element from set for this subset (b) Print seperator for subsets i.e., newline Example: Set = [a,b,c] power_set_size = pow(2, 3) = 8 Run for binary counter = 000 to 111 Value of Counter 000 001 011 100 101 110 -> -> -> -> -> -> Subset Empty set a ab c ac bc

111 Program: ? #include <stdio.h> #include <math.h>

-> abc

void printPowerSet(char *set, int set_size) { /*set_size of power set of a set with set_size n is (2**n -1)*/ unsigned int pow_set_size = pow(2, set_size); int counter, j; /*Run from counter 000..0 to 111..1*/ for(counter = 0; counter < pow_set_size; counter++) { for(j = 0; j < set_size; j++) { /* Check if jth bit in the counter is set If set then pront jth element from set */ if(counter & (1<<j)) printf("%c", set[j]); } printf("\n"); } } /*Driver program to test printPowerSet*/ int main() { char set[] = {'a','b','c'}; printPowerSet(set, 3); getchar(); return 0; } Time Complexity: O(n2^n) Change/add only one character and print * exactly 20 times June 22, 2009 In the below code, change/add only one character and print * exactly 20 times. int main() { int i, n = 20; for (i = 0; i < n; i--) printf("*"); getchar(); return 0; }

Solutions: 1. Replace i by n in for loop's third expression ? #include <stdio.h> int main() { int i, n = 20; for (i = 0; i < n; n--) printf("*"); getchar(); return 0; } 2. Put '-' before i in for loop's second expression ? #include <stdio.h> int main() { int i, n = 20; for (i = 0; -i < n; i--) printf("*"); getchar(); return 0; } 3. Replace < by + in for loop's second expression ? #include <stdio.h> int main() { int i, n = 20; for (i = 0; i + n; i--) printf("*"); getchar(); return 0; } Let's extend the problem little. Change/add only one character and print '*' exactly 21 times. Solution: Put negation operator before i in for loop's second expression. Explanation: Negation operator converts the number into its one's complement. No. One's complement 0 (00000..00) -1 (1111..11) -1 (11..1111) 0 (00..0000) -2 (11..1110) 1 (00..0001) -3 (11..1101) 2 (00..0010) ............................................... -20 (11..01100) 19 (00..10011) ?

#include <stdio.h> int main() { int i, n = 20; for (i = 0; ~i < n; i--) printf("*"); getchar(); return 0; } Efficient way to multiply with 7 May 30, 2009 We can multiply a number by 7 using bitwise operator. First left shift the number by 3 bits (you will get 8n) then subtract the original numberfrom the shifted number and return the difference (8n n). Program: ? # include<stdio.h> int multiplyBySeven(unsigned int n) { /* Note the inner bracket here. This is needed because precedence of '-' operator is higher than '<<' */ return ((n<<3) - n); } /* Driver program to test above function */ int main() { unsigned int n = 4; printf("%u", multiplyBySeven(n)); getchar(); return 0; } Time Complexity: O(1) Space Complexity: O(1) Note: Works only for positive integers. Same concept can be used for fast multiplication by 9 or other numbers. Majority Element May 30, 2009 Majority Element: A majority element in an array A[] of size n is an element that appears more than n/2 times (and hence there is at most one such element). Write a function which takes an array and emits the majority element (if it exists), otherwise prints NONE as follows:

I/P : 3 3 4 2 4 4 2 4 4 O/P : 4 I/P : 3 3 4 2 4 4 2 4 O/P : NONE METHOD 1 (Basic) The basic solution is to have two loops and keep track of maximum count for all different elements. If maximum count becomes greater than n/2 then break the loops and return the element having maximum count. If maximum count doesnt become more than n/2 then majority element doesnt exist. Time Complexity: O(n*n). Auxiliary Space : O(1).

METHOD 2 (Using Binary Search Tree) Thanks to Sachin Midha for suggesting this solution. Node of the Binary Search Tree (used in this approach) will be as follows. ? struct tree { int element; int count; }BST; Insert elements in BST one by one and if an element is already present then increment the count of the node. At any stage, if count of a node becomes more than n/2 then return. The method works well for the cases where n/2+1 occurrences of the majority element is present in the starting of the array, for example {1, 1, 1, 1, 1, 2, 3, 4}. Time Complexity: If a binary search tree is used then time complexity will be O(n^2). If a selfbalancing-binary-search tree is used then O(nlogn) Auxiliary Space: O(n)

METHOD 3 (Using Moores Voting Algorithm) This is a two step process. 1. Get an element occurring most of the time in the array. This phase will make sure that if there is a majority element then it will return that only. 2. Check if the element obtained from above step is majority element. 1. Finding a Candidate: The algorithm for first phase that works in O(n) is known as Moores Voting Algorithm. Basic idea of the algorithm is if we cancel out each occurrence of an element e with all the other elements that are different from e then e will exist till end if it is a majority element. findCandidate(a[], size) 1. Initialize index and count of majority element maj_index = 0, count = 1 2. Loop for i = 1 to size 1

(a)If a[maj_index] == a[i] count++ (b)Else count--; (c)If count == 0 maj_index = i; count = 1 3. Return a[maj_index] Above algorithm loops through each element and maintains a count of a[maj_index], If next element is same then increments the count, if next element is not same then decrements the count, and if the count reaches 0 then changes the maj_index to the current element and sets count to 1. First Phase algorithm gives us a candidate element. In second phase we need to check if the candidate is really a majority element. Second phase is simple and can be easily done in O(n). We just need to check if count of the candidate element is greater than n/2. Example: A[] = 2, 2, 3, 5, 2, 2, 6 Initialize: maj_index = 0, count = 1 > candidate 2? 2, 2, 3, 5, 2, 2, 6 Same as a[maj_index] => count = 2 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 1 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 0 Since count = 0, change candidate for majority element to 5 => maj_index = 3, count = 1 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 0 Since count = 0, change candidate for majority element to 2 => maj_index = 4 2, 2, 3, 5, 2, 2, 6 Same as a[maj_index] => count = 2 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 1 Finally candidate for majority element is 2. First step uses Moores Voting Algorithm to get a candidate for majority element. 2. Check if the element obtained in step 1 is majority printMajority (a[], size) 1. Find the candidate for majority 2. If candidate is majority. i.e., appears more than n/2 times. Print the candidate 3. Else Print "NONE"

Implementation of method 3: ? /* Program for finding out majority element in an array */ # include<stdio.h> # define bool int int findCandidate(int *, int); bool isMajority(int *, int, int); /* Function to print Majority Element */ void printMajority(int a[], int size) { /* Find the candidate for Majority*/ int cand = findCandidate(a, size); /* Print the candidate if it is Majority*/ if(isMajority(a, size, cand)) printf(" %d ", cand); else printf("NO Majority Element");

/* Function to find the candidate for Majority */ int findCandidate(int a[], int size) { int maj_index = 0, count = 1; int i; for(i = 1; i < size; i++) { if(a[maj_index] == a[i]) count++; else count--; if(count == 0) { maj_index = i; count = 1; } } return a[maj_index]; } /* Function to check if the candidate occurs more than n/2 times */ bool isMajority(int a[], int size, int cand) { int i, count = 0; for (i = 0; i < size; i++) if(a[i] == cand) count++; if (count > size/2) return 1; else return 0; }

/* Driver function to test above functions */ int main() { int a[] = {1, 3, 3, 1, 2}; printMajority(a, 5); getchar(); return 0; } Time Complexity: O(n) Auxiliary Space : O(1) Now give a try to below question Given an array of 2n elements of which n elements are same and the remaining n elements are all different. Write a C program to find out the value which is present n times in the array. There is no restriction on the elements in the array. They are random (In particular they not sequential). Given an array A[] and a number x, check for pair in A[] with sum as x May 30, 2009 Write a C program that, given an array A[] of n numbers and another number x, determines whether or not there exist two elements in S whose sum is exactly x. METHOD 1 (Use Sorting) Algorithm: hasArrayTwoCandidates (A[], ar_size, sum) 1) Sort the array in non-decreasing order. 2) Initialize two index variables to find the candidate elements in the sorted array. (a) Initialize first to the leftmost index: l = 0 (b) Initialize second the rightmost index: r = ar_size-1 3) Loop while l < r. (a) If (A[l] + A[r] == sum) then return 1 (b) Else if( A[l] + A[r] < sum ) then l++ (c) Else r-4) No candidates in whole array - return 0 Time Complexity: Depends on what sorting algorithm we are using. If we are using Merge Sort or Heap Sort then (-)(nlogn). If we are using Quick Sort then O(n^2) Auxiliary Space : Again, depends on sorting algorithm. For Merge Sort or Heap Sort then O(n). If we are using quick sort then O(1). Example: Let Array be {1, 4, 45, 6, 10, -8} and sum to find be 16 Sort the array A = {-8, 1, 4, 6, 10, 45} Initialize l = 0, r = 5 A[l] + A[r] ( -8 + 45) > 16 => decrement r. Now r = 10 A[l] + A[r] ( -8 + 10) < 2 => increment l. Now l = 1 A[l] + A[r] ( 1 + 10) < 16 => increment l. Now l = 2

A[l] + A[r] ( 4 + 10) < 14 => increment l. Now l = 3 A[l] + A[r] ( 6 + 10) == 16 => Found candidates (return 1) Note: If there are more than one pair having the given sum then this algorithm reports only one. Can be easily extended for this though. Implementation: ? # include <stdio.h> # define bool int void quickSort(int *, int, int); bool hasArrayTwoCandidates(int A[], int arr_size, int sum) { int l, r; /* Sort the elements */ quickSort(A, 0, arr_size-1); /* Now look for the two candidates in the sorted array*/ l = 0; r = arr_size-1; while(l < r) { if(A[l] + A[r] == sum) return 1; else if(A[l] + A[r] < sum) l++; else // A[i] + A[j] > sum r--; } return 0; } /* Driver program to test above function */ int main() { int A[] = {1, 4, 45, 6, 10, -8}; int n = 16; int arr_size = 6; if( hasArrayTwoCandidates(A, arr_size, n)) printf("Array has two elements who's sum is 16"); else printf("Array doesn't have two elements who's sum " " is 16 "); getchar(); return 0; } /* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING PURPOSE */

void exchange(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } int partition(int A[], int si, int ei) { int x = A[ei]; int i = (si - 1); int j; for (j = si; j <= ei - 1; j++) { if(A[j] <= x) { i++; exchange(&A[i], &A[j]); } } exchange (&A[i + 1], &A[ei]); return (i + 1); } /* Implementation of Quick Sort A[] --> Array to be sorted si --> Starting index ei --> Ending index */ void quickSort(int A[], int si, int ei) { int pi; /* Partitioning index */ if(si < ei) { pi = partition(A, si, ei); quickSort(A, si, pi - 1); quickSort(A, pi + 1, ei); } }

METHOD 2 (Use Hash Map) Thanks to Bindu for suggesting this method and thanks to Shekhu for providing code. This method works in O(n) time if range of numbers is known. Let sum be the given sum and A[] be the array in which we need to find pair. 1) Initialize Binary Hash Map M[] = {0, 0, } 2) Do following for each element A[i] in A[] (a) If M[x - A[i]] is set then print the pair (A[i], x A[i]) (b) Set M[A[i]] Implementation:

? #include <stdio.h> #define MAX 100000 void printPairs(int arr[], int arr_size, int sum) { int i, temp; bool binMap[MAX] = {0}; /*initialize hash map as 0*/ for(i = 0; i < arr_size; i++) { temp = sum - arr[i]; if(temp >= 0 && binMap[temp] == 1) { printf("Pair with given sum %d is (%d, %d) \n", sum, arr[i], temp); } binMap[arr[i]] = 1; }

/* Driver program to test above function */ int main() { int A[] = {1, 4, 45, 6, 10, 8}; int n = 16; int arr_size = 6; printPairs(A, arr_size, n); getchar(); return 0; } Time Complexity: O(n) Auxiliary Space: O(R) where R is range of integers. If range of numbers include negative numbers then also it works. All we have to do for negative numbers is scale everything with reference to the smallest negative integer in the given range. Please write comments if you find any of the above codes/algorithms incorrect, or find other ways to solve the same problem. Next Power of 2 May 28, 2009 Write a function that, for a given no n, finds a number p which is greater than or equal to n and is a power of 2. IP 5 OP 8 IP 17 OP 32 IP 32

OP 32 There are plenty of solutions for this. Let us take the example of 17 to explain some of them. Method 1(Using Log of the number) 1. Calculate Position of set bit in p(next power of 2): pos = ceil(lgn) (ceiling of log n with base 2) 2. Now calculate p: p = pow(2, pos) Example Let us try for 17 pos = 5 p = 32 Method 2 (By getting the position of only set bit in result ) /* If n is a power of 2 then return n */ 1 If (n & !(n&(n-1))) then return n 2 Else keep right shifting n until it becomes zero and count no of shifts a. Initialize: count = 0 b. While n ! = 0 n = n>>1 count = count + 1 /* Now count has the position of set bit in result */ 3 Return (1 << count) Example: Let us try for 17 count = 5 p = 32 ? unsigned int nextPowerOf2(unsigned int n) { unsigned count = 0; /* First n in the below condition is for the case where n is 0*/ if (n & !(n&(n-1))) return n; while( n != 0) { n >>= 1; count += 1; } return 1<<count;

} /* Driver program to test above function */ int main() { unsigned int n = 0; printf("%d", nextPowerOf2(n)); getchar(); return 0; } Method 3(Shift result one by one) Thanks to coderyogi for suggesting this method . This method is a variation of method 2 where instead of getting count, we shift the result one by one in a loop. ? unsigned int nextPowerOf2(unsigned int n) { unsigned int p = 1; if (n & !(n & (n - 1))) return n; while (p < n) { p <<= 1; } return p; } /* Driver program to test above function */ int main() { unsigned int n = 5; printf("%d", nextPowerOf2(n)); getchar(); return 0; } Time Complexity: O(lgn) Method 4(Customized and Fast) 1. Subtract n by 1 n = n -1 2. Set all bits after the leftmost set bit. /* Below solution works only if integer is 32 bits */ n = n | (n >> 1); n = n | (n >> 2); n = n | (n >> 4); n = n | (n >> 8); n = n | (n >> 16);

3. Return n + 1 Example: Steps 1 & 3 of above algorithm are to handle cases of power of 2 numbers e.g., 1, 2, 4, 8, 16, Let us try for 17(10001) step 1 n = n - 1 = 16 (10000) step 2 n = n | n >> 1 n = 10000 | 01000 n = 11000 n = n | n >> 2 n = 11000 | 00110 n = 11110 n = n | n >> 4 n = 11110 | 00001 n = 11111 n = n | n >> 8 n = 11111 | 00000 n = 11111 n = n | n >> 16 n = 11110 | 00000 n = 11111 step 3: Return n+1 We get n + 1 as 100000 (32) Program: ? # include <stdio.h> /* Finds next power of two for n. If n itself is a power of two then returns n*/ unsigned int nextPowerOf2(unsigned int n) { n--; n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16; n++; return n; } /* Driver program to test above function */ int main() { unsigned int n = 5; printf("%d", nextPowerOf2(n));

getchar(); return 0; } Time Complexity: O(lgn) A Program to check if strings are rotations of each other or not May 26, 2009 Given a string s1 and a string s2, write a snippet to say whether s2 is a rotation of s1 using only one call to strstr routine? (eg given s1 = ABCD and s2 = CDAB, return true, given s1 = ABCD, and s2 = ACBD , return false) Algorithm: areRotations(str1, str2) 1. Create a temp string and store concatenation of str1 to str1 in temp. temp = str1.str1 2. If str2 is a substring of temp then str1 and str2 are rotations of each other. Example: str1 = "ABACD" str2 = "CDABA" temp = str1.str1 = "ABACDABACD" Since str2 is a substring of temp, str1 and str2 are rotations of each other. Implementation: ? # include <stdio.h> # include <string.h> # include <stdlib.h> /* Function checks if passed strings (str1 and str2) are rotations of each other */ int areRotations(char *str1, char *str2) { int size1 = strlen(str1); int size2 = strlen(str2); char *temp; void *ptr; /* Check if sizes of two strings are same */ if(size1 != size2) return 0; /* Create a temp string with value str1.str1 */ temp = (char *)malloc(sizeof(char)*size1*2 + 1); temp[0] = '\0'; strcat(temp, str1); strcat(temp, str1);

/* Now check if str2 is a substring of temp */ ptr = strstr(temp, str2); /* strstr returns NULL if the second string is NOT a substring of first string */ if(ptr != NULL) return 1; else return 0; } /* Driver program to test areRotations */ int main() { char *str1 = "ABCD"; char *str2 = "ABCDA"; if(areRotations(str1, str2)) printf("Strings are rotations of each other"); else printf("Strings are not rotations of each other"); getchar(); return 0;

Library Functions Used: strstr: strstr finds a sub-string within a string. Prototype: char * strstr(const char *s1, const char *s2); See http://www.lix.polytechnique.fr/Labo/Leo.Liberti/public/computing/prog/c/C/MAN/strstr.ht m for more details strcat: strncat concatenate two strings Prototype: char *strcat(char *dest, const char *src); See http://www.lix.polytechnique.fr/Labo/Leo.Liberti/public/computing/prog/c/C/MAN/strcat.ht m for more details Time Complexity: Time complexity of this problem depends on the implementation of strstr function. If implementation of strstr is done using KMP matcher then complexity of the above program is (-)(n1 + n2) where n1 and n2 are lengths of strings. KMP matcher takes (-)(n) time to find a substrng in a string of length n where length of substring is assumed to be smaller than the string. Remove characters from the first string which are present in the second string May 23, 2009 Write an efficient C function that takes two strings as arguments and removes the characters from first string which are present in second string (mask string).

Algorithm: Let first input string betest string and the string which has characters to be removed from first string be mask 1: Initialize: res_ind = 0 /* index to keep track of processing of each character in i/p string */ ip_ind = 0 /* index to keep track of processing of each character in the resultant string */ 2: Construct count array from mask_str. Count array would be: (We can use Boolean array here instead of int count array because we dont need count, we need to know only if character is present in mask string) count['a'] = 1 count['k'] = 1 count['m'] = 1 count['s'] = 1 3: Process each character of the input string and if count of that character is 0 then only add the character to the resultant string. str = tet tringng // s has been removed because s was present in mask_str but we we have got two extra characters ng ip_ind = 11 res_ind = 9 4: Put a \0 at the end of the string? Implementation: ? #include <stdio.h> #include <stdlib.h> #define NO_OF_CHARS 256 /* Returns an array of size 256 containg count of characters in the passed char array */ int *getCharCountArray(char *str) { int *count = (int *)calloc(sizeof(int), NO_OF_CHARS); int i; for (i = 0; *(str+i); i++) count[*(str+i)]++; return count; } /* removeDirtyChars takes two string as arguments: First string (str) is the one from where function removes dirty characters. Second string is the string which contain all dirty characters which need to be removed from first string */ char *removeDirtyChars(char *str, char *mask_str) { int *count = getCharCountArray(mask_str); int ip_ind = 0, res_ind = 0; char temp; while(*(str + ip_ind)) { temp = *(str + ip_ind); if(count[temp] == 0) { *(str + res_ind) = *(str + ip_ind);

res_ind++; } ip_ind++; } /* After above step string is ngring. Removing extra "iittg" after string*/ *(str+res_ind) = '\0'; return str; } /* Driver program to test getCharCountArray*/ int main() { char mask_str[] = "mask"; char str[] = "geeksforgeeks"; printf("%s", removeDirtyChars(str, mask_str)); getchar(); return 0; } Time Complexity: O(m+n) Where m is the length of mask string and n is the length of the input string. Print all the duplicates in the input string. March 22, 2009 Write an efficient C program to print all the duplicates and their counts in the input string Algorithm: Let input string be geeksforgeeks 1: Construct character count array from the input string. count['e'] = 4 count['g'] = 2 count['k'] = 2 2: Print all the indexes from the constructed array which have value greater than 0. Solution ? # include <stdio.h> # include <stdlib.h> # define NO_OF_CHARS 256 /* Returns an array of size 256 containg count of characters in the passed char array */ int *getCharCountArray(char *str) { int *count = (int *)calloc(sizeof(int), NO_OF_CHARS); int i; for (i = 0; *(str+i); i++) count[*(str+i)]++;

return count; } /* Print duplicates present in the passed string */ void printDups(char *str) { int *count = getCharCountArray(str); int i; char temp; for (i = 0; i < NO_OF_CHARS; i++) if(count[i] > 1) printf("%c, count = %d \n", i, count[i]);

/* Driver program to test to pront printDups*/ int main() { char str[] = "test string"; printDups(str); getchar(); return 0; } Time Complexity: O(n) Remove all duplicates from the input string. March 22, 2009 Below are the different methods to remove duplicates in a string. METHOD 1 (Use Sorting) Algorithm: 1) Sort the elements. 2) Now in a loop, remove duplicates by comparing the current character and previous character. 3) Remove extra characters at the end of the resultant string. Example: Input string: geeksforgeeks 1) Sort the characters eeeefggkkosss 2) Remove duplicates efgkosgkkosss 3) Remove extra characters efgkos Note that, this method doesnt keep the original order of the input string. For example, if we are to remove duplicates for geeksforgeeks and keep the order of characters same, then output

should be geksfor, but above function returns efgkos. We can modify this method by storing the original order. METHOD 2 keeps the order same. Implementation: ? # include <stdio.h> # include <stdlib.h> /* Function to remove duplicates in a sorted array */ char *removeDupsSorted(char *str); /* Utitlity function to sort array A[] */ void quickSort(char A[], int si, int ei); /* Function removes duplicate characters from the string This function work in-place and fills null characters in the extra space left */ char *removeDups(char *str) { int len = strlen(str); quickSort(str, 0, len-1); return removeDupsSorted(str); } /* Function to remove duplicates in a sorted array */ char *removeDupsSorted(char *str) { int res_ind = 1, ip_ind = 1; /* In place removal of duplicate characters*/ while(*(str + ip_ind)) { if(*(str + ip_ind) != *(str + ip_ind - 1)) { *(str + res_ind) = *(str + ip_ind); res_ind++; } ip_ind++; } /* After above step string is stringiittg. Removing extra iittg after string*/ *(str + res_ind) = '\0'; } /* Driver program to test removeDups */ int main() { char str[] = "eeeefggkkosss"; printf("%s", removeDups(str)); getchar(); return 0; } return str;

/* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING PURPOSE */ void exchange(char *a, char *b) { char temp; temp = *a; *a = *b; *b = temp; } int partition(char A[], int si, int ei) { char x = A[ei]; int i = (si - 1); int j; for (j = si; j <= ei - 1; j++) { if(A[j] <= x) { i++; exchange(&A[i], &A[j]); } } exchange (&A[i + 1], &A[ei]); return (i + 1); } /* Implementation of Quick Sort A[] --> Array to be sorted si --> Starting index ei --> Ending index */ void quickSort(char A[], int si, int ei) { int pi; /* Partitioning index */ if(si < ei) { pi = partition(A, si, ei); quickSort(A, si, pi - 1); quickSort(A, pi + 1, ei); } } Time Complexity: O(nlogn) If we use some nlogn sorting algorithm instead of quicksort.

METHOD 2 (Use Hashing ) Algorithm: 1: Initialize: str = "test string" /* input string */

/* index to keep track of location of next character in i/p string */ ip_ind = 0 /* index to keep track of location of next character in the resultant string */ bin_hash[0..255] = {0,0, .} /* Binary hash to see if character is already processed or not */ 2: Do following for each character *(str + ip_ind) in input string: (a) if bin_hash is not set for *(str + ip_ind) then // if program sees the character *(str + ip_ind) first time (i) Set bin_hash for *(str + ip_ind) (ii) Move *(str + ip_ind) to the resultant string. This is done in-place. (iii) res_ind++ (b) ip_ind++ /* String obtained after this step is "te sringng" */ 3: Remove extra characters at the end of the resultant string. /* String obtained after this step is "te sring" */ Implementation: ? # include <stdio.h> # include <stdlib.h> # define NO_OF_CHARS 256 # define bool int /* Function removes duplicate characters from the string This function work in-place and fills null characters in the extra space left */ char *removeDups(char *str) { bool bin_hash[NO_OF_CHARS] = {0}; int ip_ind = 0, res_ind = 0; char temp; /* In place removal of duplicate characters*/ while(*(str + ip_ind)) { temp = *(str + ip_ind); if(bin_hash[temp] == 0) { bin_hash[temp] = 1; *(str + res_ind) = *(str + ip_ind); res_ind++; } ip_ind++; } /* After above step string is stringiittg. Removing extra iittg after string*/ *(str+res_ind) = '\0'; } /* Driver program to test removeDups */ return str;

res_ind = 0

int main() { char str[] = "geeksforgeeks"; printf("%s", removeDups(str)); getchar(); return 0; } Time Complexity: O(n) NOTES: * It is assumed that number of possible characters in input string are 256. NO_OF_CHARS should be changed accordingly. * calloc is used instead of malloc for memory allocations of counting array (count) to initialize allocated memory to \0. malloc() followed by memset() could also be used. * Above algorithm also works for an integer array inputs if range of the integers in array is given. Example problem is to find maximum occurring number in an input array given that the input array contain integers only between 1000 to 1100 Write a C program to calculate pow(x,n) March 22, 2009 Below solution divides the problem into subproblems of size y/2 and call the subproblems recursively. ? #include<stdio.h> /* Function to calculate x raised to the power y */ int power(int x, unsigned int y) { if( y == 0) return 1; else if (y%2 == 0) return power(x, y/2)*power(x, y/2); else return x*power(x, y/2)*power(x, y/2); } /* Program to test function power */ int main() { int x = 2; unsigned int y = 3; printf("%d", power(x, y)); getchar(); return 0; } Time Complexity: O(n) Space Complexity: O(1) Algorithmic Paradigm: Divide and conquer.

Above function can be optimized to O(logn) by calculating power(x, y/2) only once and storing it. ? /* Function to calculate x raised to the power y in O(logn)*/ int power(int x, unsigned int y) { int temp; if( y == 0) return 1; temp = power(x, y/2); if (y%2 == 0) return temp*temp; else return x*temp*temp; } Time Complexity of optimized solution: O(logn) Let us extend the pow function to work for negative y and float x. ? /* Extended version of power function that can work for float x and negative y*/ #include<stdio.h> float power(float x, int y) { float temp; if( y == 0) return 1; temp = power(x, y/2); if (y%2 == 0) return temp*temp; else { if(y > 0) return x*temp*temp; else return (temp*temp)/x; } } /* Program to test function power */ int main() { float x = 2; int y = -3; printf("%f", power(x, y)); getchar(); return 0; } Return maximum occurring character in the input string March 20, 2009 Write an efficient C function to return maximum occurring character in the input string e.g., if input string is test string then function should return t.

Algorithm: Input string = test 1: Construct character count array from the input string. count['e'] = 1 count['s'] = 1 count['t'] = 2 2: Return the index of maximum value in count array (returns t). Implementation: ? #include <stdio.h> #include <stdlib.h> #define NO_OF_CHARS 256 int *getCharCountArray(char *); char getIndexOfMax(int *, int); /* Returns the maximum occurring character in the input string */ char getMaxOccuringChar(char *str) { int *count = getCharCountArray(str); return getIndexOfMax(count, NO_OF_CHARS); } /* Returns an array of size 256 containg count of characters in the passed char array */ int *getCharCountArray(char *str) { int *count = (int *)calloc(sizeof(int), NO_OF_CHARS); int i; for (i = 0; *(str+i); i++) count[*(str+i)]++; } char getIndexOfMax(int ar[], int ar_size) { int i; int max_index = 0; for(i = 1; i < ar_size; i++) if(ar[i] > ar[max_index]) max_index = i; /* free memory allocated to count */ free(ar); ar = NULL; return count;

return max_index; } int main() { char str[] = "sample string"; printf("%c", getMaxOccuringChar(str)); getchar(); return 0; } Time Complexity: O(n) Notes: If more than one character have the same and maximum count then function returns only the first one. For example if input string is test sample then function will return only t. How will you print numbers from 1 to 100 without using loop? March 22, 2009 Here is a solution that prints numbers using recursion. Other alternatives for loop statements are recursion and goto statement, but use of goto is not suggestible as a general programming practice as goto statement changes the normal program execution sequence and makes it difficult to undestand and maintain. ? #include <stdio.h> /* Prints numbers from 1 to n */ void printNos(unsigned int n) { if(n > 0) { printNos(n-1); printf("%d ", n); } return; } /* Driver program to test printNos */ int main() { printNos(100); getchar(); return 0; } Time Complexity: O(n) Now try writing a program that does the same but without any if construct. How can we sum the digits of a given number in single statement? March 22, 2009

Below are the solutions to get sum of the digits. 1. Iterative: The function has three lines instead of one line but it calculates sum in line. It can be made one line function if we pass pointer to sum. ? # include<stdio.h> int main() { int n = 687; printf(" %d ", getSum(n)); getchar(); return 0; } /* Function to get sum of digits */ int getSum(int n) { int sum; /*Single line that calculates sum*/ for(sum=0; n > 0; sum+=n%10,n/=10); return sum; }

2. Recursive Thanks to ayesha for providing the below recursive solution. ? #include<iostream> int sumDigits(int no) { return no == 0 ? 0 : no%10 + sumDigits(no/10) ; } int main(void) { printf("%d", sumDigits(1352)); getchar(); return 0; } Please write comments if you find the above codes/algorithms incorrect, or find better ways to solve the same problem.

Você também pode gostar