Skip to content

Commit

Permalink
new question added
Browse files Browse the repository at this point in the history
  • Loading branch information
arorarahul committed Jun 20, 2017
1 parent a3202f8 commit c31eb74
Show file tree
Hide file tree
Showing 7 changed files with 354 additions and 2 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ is known.
- For problems involving subsequences, we can break them down to smaller problems. Specifically for
linear array, array of length 1 less than total can be taken and a pattern can be found for dynamic programming to make recursive equations.
- Sometimes results of two DP solutions can be merged using some algo to find the final result.
- To breakdown any question to DP (recursive equation), follow the crux of the question and break
it down into a story and later generalize to form recursive equations

# Topic0: Programming Questions

Expand Down Expand Up @@ -379,7 +381,10 @@ linear array, array of length 1 less than total can be taken and a pattern can b
- [Find the longest decreasing subsequence](/dynamic-programming/question14.c)
- [Perfect hill longest subsequence](/dynamic-programming/question15.c)
- [Given two words, word1 and word2, find min operations to convert word1 to word2 with some given set of rules](/dynamic-programming/question16.c)

- [Largest sum independent set in a binary tree](/dynamic-programming/question17.c)
- [Find the number of n-bit integers which do not have any two consequent zeroes](/dynamic-programming/question18.c)
- [Given a sentence without spaces between words. Break the words in such a way that they are meaningful](/dynamic-programming/question19.c)
- [Partition problem](/dynamic-programming/question20.c)

## Some important concepts to solve algos better

Expand Down
Binary file modified dynamic-programming/a.exe
Binary file not shown.
136 changes: 136 additions & 0 deletions dynamic-programming/question17.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
Largest sum independent set in a binary tree
Independent set means no two nodes are adjacent to each other. Eg:
10
5 6
4 3 7 8
9 12 13 14 15 16 19 21
In the above tree if I choose 10, I cannot choose 5 and 6 as they are adjacent to 10.
If I choose 5, I cannot choose 10, 4 and 3 and so on.
METHOD:
Naive approach: Here there are two cases for every tree or subtree present (either to include the node
or to not include it)
Therefore LIS(root) = max {
cost(root) + cost of all its grandchildren,
cost of all its children of root
}
Therefore for each node the number of possibilities increase as we go down the tree. Hence,
exponential time complexity.
*/
//naive approach implementation
#include <stdio.h>
#include <stdlib.h>

struct node{
int data;
struct node *left;
struct node *right;
};

struct node *newNode(int data){
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}

int findMax(int a,int b){
return (a>b)?a:b;
}

int LISS(struct node *root){
if(!root){
return 0;
}
//size excluding the current node
int size_excl = LISS(root->left) + LISS(root->right);
//size including
int size_incl = 1;
if (root->left)
size_incl += LISS(root->left->left) + LISS(root->left->right);
if (root->right)
size_incl += LISS(root->right->left) + LISS(root->right->right);
return findMax(size_excl, size_incl);
}

int main(){
struct node *root = newNode(20);
root->left = newNode(8);
root->left->left = newNode(4);
root->left->right = newNode(12);
root->left->right->left = newNode(10);
root->left->right->right = newNode(14);
root->right = newNode(22);
root->right->right = newNode(25);

int size = LISS(root);
printf("size of independent set with max sum is %d\n", size);
return 0;
}


//dynamic programming approach
#include <stdio.h>
#include <stdlib.h>

struct node{
int data;
int liss;
struct node *left;
struct node *right;
};

struct node *newNode(int data){
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = data;
temp->liss = 0;
temp->left = temp->right = NULL;
return temp;
}

int findMax(int a,int b){
return (a>b)?a:b;
}

int LISS(struct node *root){
if(!root){
return 0;
}
if(root->liss){
return root->liss;
}

if(!root->left && !root->right){
return (root->liss = 1);
}
//size excluding the current node
int size_excl = LISS(root->left) + LISS(root->right);
//size including
int size_incl = 1;
if (root->left)
size_incl += LISS(root->left->left) + LISS(root->left->right);
if (root->right)
size_incl += LISS(root->right->left) + LISS(root->right->right);
return findMax(size_excl, size_incl);
}

int main(){
struct node *root = newNode(20);
root->left = newNode(8);
root->left->left = newNode(4);
root->left->right = newNode(12);
root->left->right->left = newNode(10);
root->left->right->right = newNode(14);
root->right = newNode(22);
root->right->right = newNode(25);

int size = LISS(root);
printf("size of independent set with max sum is %d\n", size);
return 0;
}
79 changes: 79 additions & 0 deletions dynamic-programming/question18.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
Find the number of n-bit integers which do not have any two consequent zeroes
Here it means that if there a number n which is represented by bits
10101.. it should not contain any two consecutive zeroes.
Since a number is represented as 0 or 1, there are in total 2^n ways to rearrange them for n bit
integer. To validate if any 0s are occuring together will take another O(n) time.
Therefore time complexity in this case is exponential.
METHOD:
DP:
Here if we have an n bit integer, it can either start from 1 or 0,
it it starts from 1 next number can be 1 also and 0 also, hence problem is broken into n-1
parts
but if it starts from 0 the next number has to be 1, it cannot be zero. Hence here problem
now is n-2 size.
Therefore
f(n) = f(n-1) + f(n-2)
This is nothing but the program to fibonacci series where memoization can be used
Time complexity: O(n)
Space complexity: O(n)
*/

#include <stdio.h>
#include <stdlib.h>

int fib(int n){
int f[n+1];
int i;
f[0] = 0;
f[1] = 1;
for(i=2;i<=n;i++){
f[i] = f[i-1] + f[i-2];
}
return f[n];
}

int main(){
int n = 9;
printf("total here is: %d\n", fib(n));
return 0;
}


//RECURSIVE
#include <stdio.h>
#include <stdlib.h>
#define MAX 100

int f[MAX];

int fibRecursive(int n){
if(f[n] == -1){ //if does not exist then only compute
if(n < 2){
f[n] = n;
}
else{
f[n] = fibRecursive(n-1) + fibRecursive(n-2);
}
}
return f[n];
}

void initialize(int n){
int i;
for(i=0; i<=n;i++){
f[i] = -1;
}
}

int main(){
int n = 9;
initialize(n);
printf("total here is: %d\n", fibRecursive(n));
return 0;
}
17 changes: 17 additions & 0 deletions dynamic-programming/question19.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Given a sentence without spaces between words. Break the words in such a
way that they are meaningful
How to test if words are meaningful or not:
Assume that there is already a hash data structure with all the meaningful words present in it.
NAIVE approach: In worst case if we try to break the word after each character, total characters
being n, n-1 spaces can be inserted. Therefore after each character either a space can be inserted
or either it cannot be inserted.
Hence 2^n-1 ways are there and total n words can be formed and to check each word O(1) time is required.
Total time complexity is exponential
METHOD:
Dynamic programming:
*/
111 changes: 111 additions & 0 deletions dynamic-programming/question20.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
Partition problem
Here we need to divide the array into two parts where the difference in the sum of the two parts
is minimum.
If we go by naive approach, we can either include an element or exclude it, like this total combinations
will be 2^n, which needs to be scanned Therefore time complexity is exponential
METHOD
DP: Here for two parts to have equal sum, the net sum of the array needs to be even. Therefore we first
check that.
When its even, we divide it by two and apply the subset sum method. Finding a subset in the array
whose sum is equal to a given value.
Therefore we use a 2d array in that case where columns indicate sum value from 1 to given value.
Rows indicate the values in the array
Each cell means, whether considering elements uptil that row, the column value is possible or not.
Therefore we get the final answer.
Time complexity: O(nk)
Space complexity: O(nk) //where k is the value of the sum.
This method cannnot be applied for large values of k
*/
//Naive approach
// #include <stdio.h>
// #include <stdlib.h>

// int isSubsetSum(int *arr, int size, int sum){
// if(!sum)
// return 1;
// if(!size && sum)
// return 0;
// if(arr[size-1]>sum)
// return isSubsetSum(arr,size-1,sum);

// return isSubsetSum(arr,size-1,sum) || isSubsetSum(arr,size-1,sum-arr[size-1]);
// }

// int findPartition(int *arr,int size){
// int sum = 0;
// int i;
// for(i=0;i<size;i++){
// sum += arr[i];
// }
// if(sum%2 !=0) return 0;

// return isSubsetSum(arr,size,sum/2);
// }

// int main(){
// int arr[] = {3,1,5,9,12};
// int size = sizeof(arr)/sizeof(arr[0]);
// if(findPartition(arr,size)){
// printf("can be divided\n");
// }else{
// printf("cannot be divided\n");
// }
// return 0;
// }

//Better method
#include <stdio.h>
#include <stdlib.h>

int findPartition(int *arr, int size){
int sum = 0;
int i, j;
for(i=0; i<size; i++){
sum += arr[i];
}

if(sum%2 !=0){
return 0;
}

int part[sum/2+1][size];

for(i=0;i<size;i++){
part[i][0] = 1;
}

for(i=0;i<size;i++){
for(j=1;j<=sum/2;j++){
part[i][j] = part[i-1][j] || part[i-1][j-arr[i]];
}
}

// uncomment this part to print table
for (i = 0; i < size; i++)
{
for (j = 0; j <= sum/2; j++)
printf ("%4d", part[i][j]);
printf("\n");
}

return part[size-1][sum/2];
}

int main(){
int arr[] = {3,1,5,9,12};
int size = sizeof(arr)/sizeof(arr[0]);
if(findPartition(arr,size)){
printf("can be divided\n");
}else{
printf("cannot be divided\n");
}
return 0;
}
6 changes: 5 additions & 1 deletion nextquestions.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,8 @@ TODO:
- DP question7 to be done
- DP question11 (method1 naive) to be done
- DP question13 and 14(printing the subsequence to be done)
- https://gsamaras.wordpress.com/code/caution-when-reading-char-with-scanf-c/
- https://gsamaras.wordpress.com/code/caution-when-reading-char-with-scanf-c/
- DP solution extension from geeks for geeks for question17 and course sol as well
- program to find fibonacci number in logn time (geeks for geeks)
- DP question 19 to be done

0 comments on commit c31eb74

Please sign in to comment.