Skip to content

Commit 5f29cc9

Browse files
committed
new question added
1 parent 87a64cc commit 5f29cc9

File tree

6 files changed

+182
-8
lines changed

6 files changed

+182
-8
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ used where if an element should be repeating a given number of times, you can ch
134134
i+given number of times to see if thats true or not.
135135
- In divide and conquer even number of multiplications can be reduced from n to logn to get the same result. Example is the pow function where the base value is square everytime and power is halved everytime to get the same answer in logn multiplications. In case the power value is odd, the result is given the base value such that power value is converted to even and then same operations are applied.
136136
- In binary search whatever the algo be, always start from the middle and compare values to the left or right. You may even compare the extreme left and the right values to see lower and upper bound or some pattern to solve the algo. But in binary search always start from the middle.
137+
- Sometimes rather than searching in left array or right array, it is better to divide into two components/groups and apply various operations like comparison, merges etc. Note: since its divide and conquer number of division should be done till the end where we will be left with one element in each group.
138+
- Sometimes, we apply binary search and on finding the middle element we apply the logic that is the crux of the algo to the middle element to find out whether to search in right array or left array.
137139

138140
# Topic0: Programming Questions
139141

@@ -320,7 +322,8 @@ i+given number of times to see if thats true or not.
320322
- [Nuts and bolts problem](/divide-and-conquer/question2.c)
321323
- [Write a custom C function to implement a pow function](/divide-and-conquer/question3.c)
322324
- [Select an element in sorted rotated array](/divide-and-conquer/question4.c)
323-
325+
- [Count inversions in an array](/divide-and-conquer/question5.c)
326+
- [Find the missing number in arithmetic progression](/divide-and-conquer/question6.c)
324327

325328
## Some important concepts to solve algos better
326329

divide-and-conquer/a.exe

410 Bytes
Binary file not shown.

divide-and-conquer/question4.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,31 @@ Space complexity: O(1) or O(logn) //iterative or recursive
3737
//METHOD2
3838
#include <stdio.h>
3939
#include <stdlib.h>
40-
40+
//recursion
4141
int search(int *arr,int start,int end, int elm){
4242
if(start > end) return -1;
4343
int mid = (start + end)/2;
4444
if(arr[mid] == elm) return mid;
4545

46-
if(arr[start] <= arr[mid]){
47-
return (elm >= arr[start] && elm <=arr[mid])?search(arr,start,mid-1,elm):search(arr,mid+1,end,elm);
48-
}
49-
return (elm >= arr[mid] && elm <= arr[end])?search(arr,mid+1,end,elm):search(arr,start,mid-1,elm);
46+
if(arr[mid] <= arr[end]){
47+
return (elm >= arr[mid] && elm <=arr[end])?search(arr,mid+1,end,elm):search(arr,start, mid-1,elm);
48+
}
49+
return (elm >= arr[start] && elm <= arr[mid])?search(arr,start,mid-1,elm):search(arr,mid+1,end,elm);
50+
}
51+
//iteration
52+
int searchIterative(int *arr, int start, int end, int elm){
53+
while(start <= end){
54+
int mid = (start + end)/2;
55+
if(arr[mid] == elm) return mid;
56+
if(arr[mid] <= arr[end]){
57+
start = (elm >= arr[mid] && elm <= arr[end])?mid+1:start;
58+
end = (elm >= arr[mid] && elm <= arr[end])?end:mid-1;
59+
}else{
60+
end = (elm >= arr[start] && elm <=arr[mid])?mid-1:end;
61+
start = (elm >= arr[start] && elm <=arr[mid])?start:mid+1;
62+
}
63+
}
64+
return -1;
5065
}
5166

5267
int main(){
@@ -56,7 +71,7 @@ int main(){
5671
while(1){
5772
printf("enter the element to be searched\n");
5873
scanf("%d",&elm);
59-
int index = search(arr,0,size-1,elm);
74+
int index = searchIterative(arr,0,size-1,elm);
6075
if(index < 0){
6176
printf("element does not exist\n");
6277
}else{

divide-and-conquer/question5.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Count inversions in an array
3+
4+
Eg: inversion means if an array is in increasing order and there is a number somewhere towards the right
5+
of which there are 3 numbers lesser than that (rather than greater than that), then it equals 3 inversions.
6+
Like this we need to check for each element
7+
Eg: 7 5 1 3 4 6 has 8 inversions
8+
9+
METHOD1:
10+
Search for each element by comparing elements towards its right
11+
Time complexity: O(n^2)
12+
Space complexity: O(1)
13+
14+
METHOD2:
15+
By divide and conquer
16+
We take the middle element and divide the array into two parts start to mid and mid+1 to end. Keep doing
17+
this till the end until we have 1 element each in the leaf. Now we will compare components one by one and
18+
merge as we did in the merge sort. Also we will increment the number of inversion if the elm in the left
19+
component is greater than element in right component. Merging will be done in the sorted order.
20+
Like this we merge all the components. Since elements are sorted while merging if first element of a component
21+
is greater than first element of second component then it will result in inversions equal to the number of
22+
elements present in the first component as they are sorted and all will be greater then the first element of
23+
second component.
24+
Time complexity T(n)= 2T(n/2)+O(n) = O(nlogn) //same as merge sort, just that merge procedure is a bit modified
25+
Space complexity: O(logn)//size of recursion stack
26+
*/
27+
28+
//merge sort implementation
29+
#include <stdio.h>
30+
#include <stdlib.h>
31+
#include <limits.h>
32+
33+
void merge(int *arr, int start, int mid,int end){
34+
int n1 = mid-start+1; //includes mid
35+
int n2 = end-mid;
36+
int left[n1+1],right[n2+1];
37+
int i,j;
38+
for(i=0;i<n1;i++){
39+
left[i]=arr[i+start];
40+
}
41+
left[n1] = INT_MAX;
42+
for(j=0;j<n2;j++){
43+
right[j] = arr[j+mid+1];
44+
}
45+
right[n2] = INT_MAX;
46+
47+
int k;
48+
i=0;j=0;
49+
for(k=start;k<=end;k++){
50+
if(left[i] <= right[j]){
51+
arr[k] = left[i];
52+
i++;
53+
}else{
54+
arr[k] = right[j];
55+
j++;
56+
}
57+
}
58+
}
59+
60+
void mergeSort(int *arr, int start, int end){
61+
if(start < end){
62+
int mid = (start + end)/2;
63+
mergeSort(arr,start,mid);
64+
mergeSort(arr,mid+1,end);
65+
merge(arr,start,mid,end);
66+
}
67+
}
68+
69+
int main(){
70+
int arr[] = {7,5,1,3,4,6};
71+
int size = sizeof(arr)/sizeof(arr[0]);
72+
73+
mergeSort(arr,0,size-1);
74+
75+
for(int i=0;i<size;i++){
76+
printf("%d\n", arr[i]);
77+
}
78+
79+
return 0;
80+
}

divide-and-conquer/question6.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Find the missing number in arithmetic progression
3+
4+
METHOD1:
5+
we need to find the common difference first. For that a reliable approach is, we have the size of array
6+
and the last term available to us and the first term also is there. Therefore by applying
7+
a+(n-1)d we can find the cd.
8+
Once we have cd, we can simply do a linear search by increment with cd and see which element is missing
9+
Time complexity: O(n) //finding cd is a constant time operation.
10+
Space complexity: O(1)
11+
12+
METHOD2:
13+
We find the cd as stated in the above method. Now, we apply binary search. We find the middle element. its
14+
index is known. BY a+(n-1)d we see whether middle element is equal to what it should be or not. If equal
15+
search in the right array else search in the left array. Keep doing this. At one point if left array if
16+
no longer there then middle element index is the culprit.
17+
Time complexity: O(logn)
18+
Space complexity :O(1) or O(logn) //iterative or recursive
19+
*/
20+
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
24+
struct node{
25+
int index;
26+
int elm;
27+
};
28+
29+
struct node *newNode(int index, int elm){
30+
struct node *temp = (struct node *)malloc(sizeof(struct node));
31+
temp->index = index;
32+
temp->elm = elm;
33+
return temp;
34+
}
35+
36+
struct node *searchMissing(int *arr, int start, int end, int cd){
37+
if(start > end){
38+
return NULL;
39+
}
40+
int mid = (start + end)/2;
41+
int tmid = arr[0] + mid*cd;
42+
struct node *temp = NULL;
43+
if(mid>0 && arr[mid]-arr[mid-1] != cd){ //checking to the left and right of
44+
temp = newNode(mid, arr[mid-1]+cd);
45+
return temp;
46+
}
47+
if(arr[mid+1]-arr[mid] != cd){
48+
temp = newNode(mid+1,arr[mid]+cd);
49+
return temp;
50+
}
51+
struct node *left = NULL; struct node *right= NULL;
52+
if(arr[mid] == tmid){
53+
return searchMissing(arr,mid+1,end,cd);
54+
}
55+
return searchMissing(arr,start,mid-1,cd);
56+
}
57+
58+
int findDifference(int *arr, int size){
59+
int temp = (arr[size-1]-arr[0])/(size-1);
60+
}
61+
62+
int main(){
63+
int arr[] = {-2,0,4,6,8,10,12,14,16,18,20};
64+
int size = sizeof(arr)/sizeof(arr[0]);
65+
66+
int cd = findDifference(arr,size);
67+
68+
struct node *missing = searchMissing(arr,0,size-1,cd);
69+
if(missing){
70+
printf("missing element is %d should be at index %d\n", missing->elm,missing->index);
71+
}else{
72+
printf("no element is missing");
73+
}
74+
return 0;
75+
}
76+

nextquestions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ TODO:
6868
- greedy question12 implementation
6969
- divide and conquer question1, method3 to be done
7070
- divide and conquer quick sort way for question2 not able to understand
71-
- better way to implement a pow function
71+
- divide and conquer question5 to be done

0 commit comments

Comments
 (0)