Skip to content

Commit cc649ad

Browse files
committed
new question added
1 parent 5f29cc9 commit cc649ad

File tree

9 files changed

+328
-5
lines changed

9 files changed

+328
-5
lines changed

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,15 @@ max edge or path to be traversed to minimize work.
133133
used where if an element should be repeating a given number of times, you can check its value at i and then
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.
136-
- 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.
136+
- 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. Also to break the recursion to return result successful condition will be a unique property trait at that index as per algo. Find that trait.
137137
- 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.
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. Eg: crux of algo if is swapping we do swapping, if comparing we do comparing, if it is applying some formula, we do that.
139+
- To write the iterative version of a recursive version follow the steps below
140+
- Replace the recursion break condition with the while loop which will run
141+
- Apply the same conditions and update the value of the variables in that condition. These variables will be a part of the while loop also. Rather than calling the function with updated values, just update the values of the variables and while loop will handle the rest
142+
- Make sure to assign both the variable values that are passed into the function in recursion while doing it in while loop as iteration
143+
- The false condition (if any false value is to be returned for validation) will come after the end of while loop
144+
- To write recursive from iterative, replace while loop condition and its opposite should be break condition of recursion and reverse the sub steps
139145

140146
# Topic0: Programming Questions
141147

@@ -324,6 +330,11 @@ i+given number of times to see if thats true or not.
324330
- [Select an element in sorted rotated array](/divide-and-conquer/question4.c)
325331
- [Count inversions in an array](/divide-and-conquer/question5.c)
326332
- [Find the missing number in arithmetic progression](/divide-and-conquer/question6.c)
333+
- [Given an array containing 1's and 0's in which all 0's appear before all 1's, count the number of 1's in the array](/divide-and-conquer/question7.c)
334+
- [Given an array with 2n integer in the formal a1,a2,a3...b1,b2,b3.. Shuffle the array to a1b1 a2b2 a3b3 ...](/divide-and-conquer/question8.c)
335+
- [Given a sorted array of non repeated integers a[1--n]. Check whether there is an index i for which a[i]=i](/divide-and-conquer/question9.c)
336+
- [Find the maximum element index in an array which is first increasing and then decreasing](/divide-and-conquer/question10.c)
337+
- [Search an element in row wise and column wise sorted 2d array](/divide-and-conquer/question11.c)
327338

328339
## Some important concepts to solve algos better
329340

divide-and-conquer/a.exe

-1.08 KB
Binary file not shown.

divide-and-conquer/question10.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
Find the maximum element index in an array which is first increasing and then decreasing
3+
4+
It means that there is an increasing sequence till i and then after that i+1 to n is a decreasing
5+
sequence. We need to find the value of i
6+
7+
METHOD1:
8+
Linear search
9+
Time complexity: O(n)
10+
Space complexity: O(1)
11+
12+
METHOD2:
13+
Binary search.
14+
Here we find middle and if the element at the middle lies in the increasing sequence
15+
search the right array else search the left array. Also for successful condition we see the the middle
16+
element has its immediate right and left lesser than it, then that is the required number.
17+
Time complexity: O(logn) //because T(n/2) + O(1)
18+
Space complexity: O(1) or O(logn) //iterative or recursive
19+
*/
20+
#include <stdio.h>
21+
#include <stdlib.h>
22+
23+
int findIndex(int *arr,int start, int end){
24+
if(start > end){
25+
return -1;
26+
}
27+
int mid = (start+end)/2;
28+
if(arr[mid] > arr[mid-1] && arr[mid] > arr[mid+1]){
29+
return mid;
30+
}
31+
if(arr[mid] < arr[mid+1] && arr[mid] > arr[mid-1]){
32+
return findIndex(arr,mid+1,end); //increasing sequence search the right one
33+
}
34+
return findIndex(arr,start,mid-1);
35+
}
36+
37+
int main(){
38+
int arr[] = {1,2,3,4,5,6,5,4,3,2,1};
39+
int size = sizeof(arr)/sizeof(arr[0]);
40+
int index = findIndex(arr,0,size-1);
41+
if(index < 0){
42+
printf("no such element exists\n");
43+
}else{
44+
printf("index with peak is %d\n", index);
45+
}
46+
return 0;
47+
}

divide-and-conquer/question11.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Search an element in row wise and column wise sorted 2d array
3+
4+
METHOD1:
5+
Naive approach, searching for an element using for loops
6+
Time complexity: O(n^2)
7+
Space complexity: O(1)
8+
9+
METHOD2:
10+
In this case it can be done in linear time. Since arrays is in sorted order top to bottom and left
11+
to right. We can start from top right. We can maintain two variable. i will traverse rows and j will
12+
traverse columns. Initial value of i will be zero and j will be n-1. Now if value to be found is
13+
lesser than top right decrease j to move towards lesser elements. If its greater increase i.
14+
Follow this and it will end up at the element required.
15+
Time complexity: O(m+n) or O(2n) if both n and m are equal
16+
Space complexity: O(1)
17+
18+
METHOD3:
19+
Binary search. Now since array is sorted row and column wise, we find the middle of the whole
20+
2d array. If the element to be found is less than this middle element then it is definately not
21+
present in the fourth quadrant (if the 2d array is divided into 4 parts).
22+
If element to be found is greater than x, then it definately cannot be a part of first quadrant.
23+
Therefore we can narrow our search down to only 3 quadrants each time
24+
Time complexity: T(k) = 3T(k/4) + O(1) //we search thirce in 3 quadrants. each quadrant has 1/4
25+
elements of total elements k. O(1) is the comparison which is done with the middle element.
26+
By masters theorem and substituting k as n^2 we get n^1.5 as time complexity
27+
Space complexity: O(1) //iterative
28+
*/
29+
//METHOD2
30+
#include <stdio.h>
31+
#include <stdlib.h>
32+
33+
int main(){
34+
int arr[4][4] = {
35+
{0,1,2,3},
36+
{4,5,6,7},
37+
{8,9,10,11},
38+
{12,13,14,15}
39+
};
40+
int size = sizeof(arr)/sizeof(arr[0]);
41+
42+
return 0;
43+
}

divide-and-conquer/question6.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,35 @@ struct node *searchMissing(int *arr, int start, int end, int cd){
4848
temp = newNode(mid+1,arr[mid]+cd);
4949
return temp;
5050
}
51-
struct node *left = NULL; struct node *right= NULL;
5251
if(arr[mid] == tmid){
5352
return searchMissing(arr,mid+1,end,cd);
5453
}
5554
return searchMissing(arr,start,mid-1,cd);
5655
}
5756

57+
struct node *searchMissingIterative(int *arr, int start, int end, int cd){
58+
struct node *temp = NULL;
59+
while(start <= end){
60+
int mid = (start + end)/2;
61+
int tmid = arr[0] + mid*cd;
62+
if(mid > 0 && arr[mid] - arr[mid-1] != cd){
63+
temp = newNode(mid,arr[mid-1]+cd);
64+
return temp;
65+
}
66+
if(arr[mid+1]-arr[mid] != cd){
67+
temp = newNode(mid+1,arr[mid]+cd);
68+
return temp;
69+
}
70+
if(arr[mid] == tmid){
71+
start = mid + 1;
72+
end = end;
73+
}else{
74+
start = start;
75+
end = mid-1;
76+
}
77+
}
78+
}
79+
5880
int findDifference(int *arr, int size){
5981
int temp = (arr[size-1]-arr[0])/(size-1);
6082
}
@@ -65,7 +87,7 @@ int main(){
6587

6688
int cd = findDifference(arr,size);
6789

68-
struct node *missing = searchMissing(arr,0,size-1,cd);
90+
struct node *missing = searchMissingIterative(arr,0,size-1,cd);
6991
if(missing){
7092
printf("missing element is %d should be at index %d\n", missing->elm,missing->index);
7193
}else{

divide-and-conquer/question7.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
Given an array containing 1's and 0's in which all 0's appear before all 1's, count the number of 1's in
3+
the array
4+
5+
METHOD1:
6+
linear search and sum
7+
Time complexity: O(n)
8+
Space complexity: O(1)
9+
10+
METHOD2:
11+
Binary search to find where 1 starts
12+
Time complexity: O(logn)
13+
Space complexity: o(1) or O(logn) //iterative or recursive
14+
*/
15+
#include <stdio.h>
16+
#include <stdlib.h>
17+
18+
int countOnes(int *arr, int start, int end,int size){
19+
if(start > end){
20+
return -1;
21+
}
22+
int mid = (start + end)/2;
23+
if(arr[mid] && !arr[mid-1]){
24+
return (size-mid);
25+
}
26+
if(arr[mid] && arr[mid-1]){
27+
return countOnes(arr,start,mid-1, size);
28+
}
29+
return countOnes(arr,mid+1,end,size);
30+
}
31+
32+
int countOnesIterative(int *arr, int start, int end, int size){
33+
while(start <= end){
34+
int mid = (start + end)/2;
35+
if(arr[mid] && !arr[mid-1]){
36+
return (size-mid);
37+
}
38+
if(arr[mid] && arr[mid-1]){
39+
start = start;
40+
end = mid-1;
41+
}else{
42+
start = mid + 1;
43+
end = end;
44+
}
45+
}
46+
}
47+
48+
int main(){
49+
int arr[] = {0,0,0,0,1,1,1,1,1};
50+
int size = sizeof(arr)/sizeof(arr[0]);
51+
int count = countOnesIterative(arr,0,size-1, size);
52+
if(count < 0){
53+
printf("there are no 1s in the array\n");
54+
}else{
55+
printf("number of 1s are %d\n", count);
56+
}
57+
return 0;
58+
}

divide-and-conquer/question8.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
Given an array with 2n integer in the formal a1,a2,a3...b1,b2,b3..
3+
Shuffle the array to a1b1 a2b2 a3b3 ...
4+
5+
Lets say the array is 1 2 3 4 | 5 6 7 8
6+
outout should be 15 26 37 48
7+
8+
METHOD1:
9+
Simply maintain two pointers, one at start and one at mid+1, and make a new array of equal size
10+
and write to that array these values one by one and increment them.
11+
Time complexity: O(n)
12+
Space complexity: O(n)
13+
14+
METHOD2:
15+
Using binary search. Here we break the solutions into two parts and take the second half of the
16+
first part and first half of the second part and swap them. Then we divide the left and right halves
17+
again into two parts, and repeat the above steps till our size goes to 2 we keep doing that.
18+
One it is 2 we will have the desired solution.
19+
Time complexity: O(nlogn) //same as merge sort because at each step work done will be equal to
20+
dividing the array into two parts T(n/2) + swapping O(n)
21+
Space complexity: O(logn) //height of the binary tree formed, which will be the space occupied by
22+
the stack
23+
*/
24+
//METHOD1 is too simple
25+
//METHOD2
26+
#include <stdio.h>
27+
#include <stdlib.h>
28+
29+
void swap(int *a, int *b){
30+
int temp = *a;
31+
*a = *b;
32+
*b = temp;
33+
}
34+
35+
void combineArrays(int *arr, int start, int end, int size){
36+
if(end-start+1 <= 2){
37+
return;
38+
}
39+
int mid = (start + end)/2;
40+
int i=(start+mid+1)/2,j=mid+1;
41+
while(i<=mid && j<=(mid+end)/2){
42+
swap(&arr[i],&arr[j]);
43+
for(int i=0; i<size;i++){
44+
printf("%d\t", arr[i]);
45+
}
46+
i++;j++;
47+
}
48+
combineArrays(arr,start,mid, size);
49+
combineArrays(arr,mid+1,end, size);
50+
}
51+
52+
// void combineArraysIterative(int *arr, int start, int end, int size){
53+
// while(end-start+1>2){
54+
// int mid = (start+end)/2;
55+
// int i=(start+mid+1)/2,j=mid+1;
56+
// while(i<=mid && j<=(mid+end)/2){
57+
// printf("swapping %d and %d\n", arr[i], arr[j]);
58+
// swap(&arr[i],&arr[j]);
59+
// i++;j++;
60+
// }
61+
// start = start;
62+
// end=mid;
63+
// }
64+
// }
65+
66+
int main(){
67+
int arr[] = {1,2,3,4,5,6,7,8};
68+
int size = sizeof(arr)/sizeof(arr[0]);
69+
combineArraysIterative(arr,0,size-1,size);
70+
71+
for(int i=0; i<size;i++){
72+
printf("%d\n", arr[i]);
73+
}
74+
return 0;
75+
}

divide-and-conquer/question9.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
Given a sorted array of non repeated integers a[1--n].
3+
Check whether there is an index i for which a[i]=i
4+
5+
METHOD1:
6+
Linear search
7+
Time complexity: O(n)
8+
Space complexity: O(1)
9+
10+
METHOD2:
11+
Ideally this question is not valid, if the numbers are starting from 1 and indexes are starting
12+
from zero, there cannot exist a case where a[i]=i because numbers cannot repeat also and they
13+
will atleast have to increase by one as they are sorted.
14+
15+
Just in case an example of repitition is taken, the way to solve the problem is using binary search
16+
We take the middle element and see if its value is greater than index, if yes then we search on left
17+
because it cannot exist in right as value atleast will increase by 1 each time and so does the index.
18+
So it can never catchup. In case value is lesser then index we will search right because value
19+
can atleast increase by one and can catch up.
20+
Time complexity: o(logn)
21+
Space complexity: O(logn) or O(1) //recursive or iterative
22+
*/
23+
#include <stdio.h>
24+
#include <stdlib.h>
25+
26+
int checkIndex(int *arr, int start, int end){
27+
if(start > end){
28+
return -1;
29+
}
30+
int mid = (start+end)/2;
31+
if(arr[mid]==mid){
32+
return mid;
33+
}
34+
if(arr[mid] > mid){
35+
return checkIndex(arr,start,mid-1);
36+
}
37+
return checkIndex(arr,mid+1,end);
38+
}
39+
40+
int checkIndexIterative(int *arr, int start, int end){
41+
while(start <= end){
42+
int mid = (start+end)/2;
43+
if(arr[mid] == mid){
44+
return mid;
45+
}
46+
if(arr[mid]>mid){
47+
end = mid-1;
48+
}else{
49+
start = mid+1;
50+
}
51+
}
52+
return -1;
53+
}
54+
55+
int main(){
56+
int arr[] = {0,0,1,2,2,3,4,7,8};
57+
int size = sizeof(arr)/sizeof(arr[0]);
58+
int index = checkIndexIterative(arr,0,size-1);
59+
if(index < 0){
60+
printf("such an element does not exist\n");
61+
}else{
62+
printf("index at which such element exists is %d\n", index);
63+
}
64+
return 0;
65+
}

nextquestions.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,6 @@ 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-
- divide and conquer question5 to be done
71+
- divide and conquer question5 to be done
72+
- make the iterative version for question8
73+
- last question of divide and conquer to be done (2d array)

0 commit comments

Comments
 (0)