-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a3202f8
commit c31eb74
Showing
7 changed files
with
354 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters