Divide and Conquer PDF
Divide and Conquer PDF
3 Binary Search 19
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1
Contents
15 Cut all the rods with some length such that the sum of cut-off length
is maximized 123
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
2
Contents
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
3
Contents
55 Merge Sort with O(1) extra space merge and O(n lg n) time 407
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
4
Contents
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
67 QuickSort 478
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
74 Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} without
using extra space 532
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
75 Smallest number with given sum of digits and sum of square of digits 539
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
5
Contents
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
6
Chapter 1
The above algorithm divides the problem into a subproblems, each of size n/b and solve
them recursively to compute the problem and the extra work done for problem is given
by f(n), i.e., the time to create the subproblems and combine their results in the above
procedure.
So, according to master theorem the runtime of the above algorithm can be expressed as:
7
Chapter 1. Advanced master theorem for divide and conquer recurrences
Not all recurrence relations can be solved with the use of the master theorem i.e. if
This theorem is an advance version of master theorem that can be used to determine running
time of divide and conquer algorithms if the recurrence is of the following form :-
8
Chapter 1. Advanced master theorem for divide and conquer recurrences
Source
https://www.geeksforgeeks.org/advanced-master-theorem-for-divide-and-conquer-recurrences/
9
Chapter 2
The idea is to use Binary Search. We fix a value for the number of pages as mid of current
minimum and maximum. We initialize minimum and maximum as 0 and sum-of-all-pages
10
Chapter 2. Allocate minimum number of pages
respectively. If a current mid can be a solution, then we search on the lower half, else we
search in higher half.
Now the question arises, how to check if a mid value is feasible or not? Basically, we need
to check if we can assign pages to all students in a way that the maximum number doesn’t
exceed current value. To do this, we sequentially assign pages to every student while the
current number of assigned pages doesn’t exceed the value. In this process, if the number
of students becomes more than m, then the solution is not feasible. Else feasible.
Below is an implementation of above idea.
C++
11
Chapter 2. Allocate minimum number of pages
12
Chapter 2. Allocate minimum number of pages
// at-last return minimum no. of pages
return result;
}
// Drivers code
int main()
{
//Number of pages in books
int arr[] = {12, 34, 67, 90};
int n = sizeof arr / sizeof arr[0];
int m = 2; //No. of students
cout << "Minimum number of pages = "
<< findPages(arr, n, m) << endl;
return 0;
}
Java
13
Chapter 2. Allocate minimum number of pages
curr_sum = arr[i];
// if students required becomes greater
// than given no. of students,return false
if (studentsRequired > m)
return false;
}
// else update curr_sum
else
curr_sum += arr[i];
}
return true;
}
// method to find minimum pages
static int findPages(int arr[], int n, int m)
{
long sum = 0;
// return -1 if no. of books is less than
// no. of students
if (n < m)
return -1;
// Count total number of pages
for (int i = 0; i < n; i++)
sum += arr[i];
// initialize start as 0 pages and end as
// total pages
int start = 0, end = (int) sum;
int result = Integer.MAX_VALUE;
// traverse until start <= end
while (start <= end)
{
// check if it is possible to distribute
// books by using mid is current minimum
int mid = (start + end) / 2;
if (isPossible(arr, n, m, mid))
{
// if yes then find the minimum distribution
result = Math.min(result, mid);
// as we are finding minimum and books
// are sorted so reduce end = mid -1
// that means
14
Chapter 2. Allocate minimum number of pages
end = mid - 1;
}
else
// if not possible means pages should be
// increased so update start = mid + 1
start = mid + 1;
}
// at-last return minimum no. of pages
return result;
}
// Driver Method
public static void main(String[] args)
{
//Number of pages in books
int arr[] = {12, 34, 67, 90};
int m = 2; //No. of students
System.out.println("Minimum number of pages = " +
findPages(arr, arr.length, m));
}
}
C#
15
Chapter 2. Allocate minimum number of pages
16
Chapter 2. Allocate minimum number of pages
17
Chapter 2. Allocate minimum number of pages
Output :
Improved By : vt_m
Source
https://www.geeksforgeeks.org/allocate-minimum-number-pages/
18
Chapter 3
Binary Search
Example :
Image Source : http://www.nyckidd.com/bob/Linear%20Search%20and%20Binary%
20Search_WorkingCopy.pdf
19
Chapter 3. Binary Search
The idea of binary search is to use the information that the array is sorted and reduce the
time complexity to O(Log n).
We basically ignore half of the elements just after one comparison.
20
Chapter 3. Binary Search
{
int arr[] = {2, 3, 4, 10, 40};
int n = sizeof(arr)/ sizeof(arr[0]);
int x = 10;
int result = binarySearch(arr, 0, n-1, x);
(result == -1)? printf("Element is not present in array")
: printf("Element is present at index %d",
result);
return 0;
}
Java
21
Chapter 3. Binary Search
Python
22
Chapter 3. Binary Search
C#
23
Chapter 3. Binary Search
int n = arr.Length;
int x = 10;
int result = binarySearch(arr, 0, n-1, x);
if (result == -1)
Console.WriteLine("Element not present");
else
Console.WriteLine("Element found at index "
+ result);
}
}
// This code is contributed by Sam007.
PHP
<?php
// PHP program to implement
// recursive Binary Search
// A recursive binary search
// function. It returns location
// of x in given array arr[l..r]
// is present, otherwise -1
function binarySearch($arr, $l, $r, $x)
{
if ($r >= $l)
{
$mid = $l + ($r - $l) / 2;
// If the element is present
// at the middle itself
if ($arr[$mid] == $x)
return floor($mid);
// If element is smaller than
// mid, then it can only be
// present in left subarray
if ($arr[$mid] > $x)
return binarySearch($arr, $l,
$mid - 1, $x);
// Else the element can only
// be present in right subarray
return binarySearch($arr, $mid + 1,
$r, $x);
}
24
Chapter 3. Binary Search
// We reach here when element
// is not present in array
return -1;
}
// Driver Code
$arr = array(2, 3, 4, 10, 40);
$n = count($arr);
$x = 10;
$result = binarySearch($arr, 0, $n - 1, $x);
if(($result == -1))
echo "Element is not present in array";
else
echo "Element is present at index ",
$result;
// This code is contributed by anuj_67.
?>
Output :
25
Chapter 3. Binary Search
Java
26
Chapter 3. Binary Search
}
// if we reach here, then element was
// not present
return -1;
}
// Driver method to test above
public static void main(String args[])
{
BinarySearch ob = new BinarySearch();
int arr[] = {2, 3, 4, 10, 40};
int n = arr.length;
int x = 10;
int result = ob.binarySearch(arr, x);
if (result == -1)
System.out.println("Element not present");
else
System.out.println("Element found at " +
"index " + result);
}
}
Python
27
Chapter 3. Binary Search
C#
28
Chapter 3. Binary Search
return -1;
}
// Driver method to test above
public static void Main()
{
int []arr = {2, 3, 4, 10, 40};
int n = arr.Length;
int x = 10;
int result = binarySearch(arr, x);
if (result == -1)
Console.WriteLine("Element not present");
else
Console.WriteLine("Element found at " +
"index " + result);
}
}
// This code is contributed by Sam007
PHP
<?php
// PHP program to implement
// iterative Binary Search
// A iterative binary search
// function. It returns location
// of x in given array arr[l..r]
// if present, otherwise -1
function binarySearch($arr, $l,
$r, $x)
{
while ($l <= $r)
{
$m = $l + ($r - $l) / 2;
// Check if x is present at mid
if ($arr[$m] == $x)
return floor($m);
// If x greater, ignore
// left half
if ($arr[$m] < $x)
$l = $m + 1;
// If x is smaller,
// ignore right half
else
29
Chapter 3. Binary Search
$r = $m - 1;
}
// if we reach here, then
// element was not present
return -1;
}
// Driver Code
$arr = array(2, 3, 4, 10, 40);
$n = count($arr);
$x = 10;
$result = binarySearch($arr, 0,
$n - 1, $x);
if(($result == -1))
echo "Element is not present in array";
else
echo "Element is present at index ",
$result;
// This code is contributed by anuj_67.
?>
Output :
Time Complexity:
The time complexity of Binary Search can be written as
T(n) = T(n/2) + c
The above recurrence can be solved either using Recurrence T ree method or Mas-
ter method. It falls in case II of Master Method and solution of the recurrence is
.
Auxiliary Space: O(1) in case of iterative implementation. In case of recursive implemen-
tation, O(Logn) recursion call stack space.
Algorithmic Paradigm: Decrease and Conquer.
Interesting articles based on Binary Search.
30
Chapter 3. Binary Search
Improved By : vt_m
Source
https://www.geeksforgeeks.org/binary-search/
31
Chapter 4
32
Chapter 4. Binary Search (bisect) in Python
Output:
Output:
33
Chapter 4. Binary Search (bisect) in Python
else:
return -1
a = [1, 2, 4, 4]
x = int(4)
res = BinarySearch(a, x)
if res == -1:
print(x, "is absent")
else:
print("Last occurrence of", x, "is present at", res)
Output:
Please refer Binary Search for writing your own Binary Search code.
Reference :
https://docs.python.org/3/library/bisect.html
Source
https://www.geeksforgeeks.org/binary-search-bisect-in-python/
34
Chapter 5
• Here, start node(set to Head of list), and the last node(set to NULL initially) are
given.
• Middle is calculated using two pointers approach.
• If middle’s data matches the required value of search, return it.
• Else if midele’s data < value, move to upper half(setting last to midele’s next).
• Else go to lower half(setting last to middle).
• The condition to come out is, either element found or entire list is traversed. When
entire list is traversed, last points to start i.e. last -> next == start.
In main function, function InsertAtHead inserts value at the beginning of linked list.
Inserting such values(for sake of simplicity) so that the list created is sorted.
Examples :
35
Chapter 5. Binary Search on Singly Linked List
36
Chapter 5. Binary Search on Singly Linked List
37
Chapter 5. Binary Search on Singly Linked List
printf("Present");
return 0;
}
Output:
Present
Source
https://www.geeksforgeeks.org/binary-search-on-singly-linked-list/
38
Chapter 6
Input : list = 1, 5, 7, 10, 12, 14, 15, 18, 20, 22, 25, 27, 30, 64, 110, 220
key = 7
Output : 7 found in list
Input : list = 1, 5, 7, 10, 12, 14, 15, 18, 20, 22, 25, 27, 30, 64, 110, 220
key = 111
Output : 111 not found in list
39
Chapter 6. Binary Search using pthread
40
Chapter 6. Binary Search using pthread
{
pthread_t threads[MAX_THREAD];
for (int i = 0; i < MAX_THREAD; i++)
pthread_create(&threads[i], NULL, binary_search, (void*)NULL);
for (int i = 0; i < MAX_THREAD; i++)
pthread_join(threads[i], NULL);
// key found in array
if (found)
cout << key << " found in array" << endl;
// key not found in array
else
cout << key << " not found in array" << endl;
return 0;
}
Output:
Source
https://www.geeksforgeeks.org/binary-search-using-pthread/
41
Chapter 7
42
Chapter 7. Check for Majority Element in a sorted array
Java
43
Chapter 7. Check for Majority Element in a sorted array
Python
44
Chapter 7. Check for Majority Element in a sorted array
C#
45
Chapter 7. Check for Majority Element in a sorted array
// This code is contributed by Sam007
PHP
<?php
// PHP Program to check for
// majority element in a
// sorted array
// function returns majority
// element in a sorted array
function isMajority($arr, $n, $x)
{
$i;
// get last index according
// to n (even or odd)
$last_index = $n % 2? ($n / 2 + 1): ($n / 2);
// search for first occurrence
// of x in arr[]
for ($i = 0; $i < $last_index; $i++)
{
// check if x is present and
// is present more than n/2
// times
if ($arr[$i] == $x && $arr[$i + $n / 2] == $x)
return 1;
}
return 0;
}
// Driver Code
$arr = array(1, 2, 3, 4, 4, 4, 4);
$n = sizeof($arr);
$x = 4;
if (isMajority($arr, $n, $x))
echo $x, " appears more than "
, floor($n / 2), " times in arr[]";
else
echo $x, "does not appear more than "
, floor($n / 2), "times in arr[]";
// This code is contributed by Ajit
?>
46
Chapter 7. Check for Majority Element in a sorted array
Output :
47
Chapter 7. Check for Majority Element in a sorted array
is true:
(i) mid == 0 and arr[mid] == x
(ii) arr[mid-1] < x and arr[mid] == x
*/
if ( (mid == 0 || x > arr[mid-1]) && (arr[mid] == x) )
return mid;
else if (x > arr[mid])
return _binarySearch(arr, (mid + 1), high, x);
else
return _binarySearch(arr, low, (mid -1), x);
}
return -1;
}
/* Driver program to check above functions */
int main()
{
int arr[] = {1, 2, 3, 3, 3, 3, 10};
int n = sizeof(arr)/sizeof(arr[0]);
int x = 3;
if (isMajority(arr, n, x))
printf("%d appears more than %d times in arr[]",
x, n/2);
else
printf("%d does not appear more than %d times in arr[]",
x, n/2);
return 0;
}
Java
48
Chapter 7. Check for Majority Element in a sorted array
49
Chapter 7. Check for Majority Element in a sorted array
Python
50
Chapter 7. Check for Majority Element in a sorted array
C#
51
Chapter 7. Check for Majority Element in a sorted array
// of size n
static bool isMajority(int[] arr, int n, int x)
{
// Find the index of first occurrence
// of x in arr[]
int i = _binarySearch(arr, 0, n - 1, x);
// If element is not present at all,
// return false
if (i == -1)
return false;
// check if the element is present
// more than n/2 times
if (((i + n / 2) <= (n - 1)) &&
arr[i + n / 2] == x)
return true;
else
return false;
}
//Driver code
public static void Main()
{
int[] arr = { 1, 2, 3, 3, 3, 3, 10 };
int n = arr.Length;
int x = 3;
if (isMajority(arr, n, x) == true)
Console.Write(x + " appears more than " +
n / 2 + " times in arr[]");
else
Console.Write(x + " does not appear more than " +
n / 2 + " times in arr[]");
}
}
// This code is contributed by Sam007
Output:
52
Chapter 7. Check for Majority Element in a sorted array
Source
https://www.geeksforgeeks.org/check-for-majority-element-in-a-sorted-array/
53
Chapter 8
The Brute force solution is O(n^2), compute the distance between each pair and return the
smallest. We can calculate the smallest distance in O(nLogn) time using Divide and Conquer
strategy. In this post, a O(n x (Logn)^2) approach is discussed. We will be discussing a
O(nLogn) approach in a separate post.
Algorithm
Following are the detailed steps of a O(n (Logn)^2) algortihm.
Input: An array of n points P[]
Output: The smallest distance between two points in the given array.
As a pre-processing step, input array is sorted according to x coordinates.
1) Find the middle point in the sorted array, we can take P[n/2] as middle point.
2) Divide the given array in two halves. The first subarray contains points from P[0] to
P[n/2]. The second subarray contains points from P[n/2+1] to P[n-1].
3) Recursively find the smallest distances in both subarrays. Let the distances be dl and
dr. Find the minimum of dl and dr. Let the minimum be d.
54
Chapter 8. Closest Pair of Points using Divide and Conquer algorithm
4) From above 3 steps, we have an upper bound d of minimum distance. Now we need to
consider the pairs such that one point in pair is from left half and other is from right half.
Consider the vertical line passing through passing through P[n/2] and find all points whose
x coordinate is closer than d to the middle vertical line. Build an array strip[] of all such
points.
55
Chapter 8. Closest Pair of Points using Divide and Conquer algorithm
5) Sort the array strip[] according to y coordinates. This step is O(nLogn). It can be
optimized to O(n) by recursively sorting and merging.
6) Find the smallest distance in strip[]. This is tricky. From first look, it seems to be a
O(n^2) step, but it is actually O(n). It can be proved geometrically that for every point in
strip, we only need to check at most 7 points after it (note that strip is sorted according to
Y coordinate). See thisfor more analysis.
7) Finally return the minimum of d and distance calculated in above step (step 6)
Implementation
Following is C/C++ implementation of the above algorithm.
// A divide and conquer program in C/C++ to find the smallest distance from a
// given set of points.
#include <stdio.h>
56
Chapter 8. Closest Pair of Points using Divide and Conquer algorithm
#include <float.h>
#include <stdlib.h>
#include <math.h>
// A structure to represent a Point in 2D plane
struct Point
{
int x, y;
};
/* Following two functions are needed for library function qsort().
Refer: http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */
// Needed to sort array of points according to X coordinate
int compareX(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->x - p2->x);
}
// Needed to sort array of points according to Y coordinate
int compareY(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->y - p2->y);
}
// A utility function to find the distance between two points
float dist(Point p1, Point p2)
{
return sqrt( (p1.x - p2.x)*(p1.x - p2.x) +
(p1.y - p2.y)*(p1.y - p2.y)
);
}
// A Brute Force method to return the smallest distance between two points
// in P[] of size n
float bruteForce(Point P[], int n)
{
float min = FLT_MAX;
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
if (dist(P[i], P[j]) < min)
min = dist(P[i], P[j]);
return min;
}
// A utility function to find minimum of two float values
float min(float x, float y)
57
Chapter 8. Closest Pair of Points using Divide and Conquer algorithm
{
return (x < y)? x : y;
}
// A utility function to find the distance beween the closest points of
// strip of given size. All points in strip[] are sorted accordint to
// y coordinate. They all have an upper bound on minimum distance as d.
// Note that this method seems to be a O(n^2) method, but it's a O(n)
// method as the inner loop runs at most 6 times
float stripClosest(Point strip[], int size, float d)
{
float min = d; // Initialize the minimum distance as d
qsort(strip, size, sizeof(Point), compareY);
// Pick all points one by one and try the next points till the difference
// between y coordinates is smaller than d.
// This is a proven fact that this loop runs at most 6 times
for (int i = 0; i < size; ++i)
for (int j = i+1; j < size && (strip[j].y - strip[i].y) < min; ++j)
if (dist(strip[i],strip[j]) < min)
min = dist(strip[i], strip[j]);
return min;
}
// A recursive function to find the smallest distance. The array P contains
// all points sorted according to x coordinate
float closestUtil(Point P[], int n)
{
// If there are 2 or 3 points, then use brute force
if (n <= 3)
return bruteForce(P, n);
// Find the middle point
int mid = n/2;
Point midPoint = P[mid];
// Consider the vertical line passing through the middle point
// calculate the smallest distance dl on left of middle point and
// dr on right side
float dl = closestUtil(P, mid);
float dr = closestUtil(P + mid, n-mid);
// Find the smaller of two distances
float d = min(dl, dr);
58
Chapter 8. Closest Pair of Points using Divide and Conquer algorithm
// Build an array strip[] that contains points close (closer than d)
// to the line passing through the middle point
Point strip[n];
int j = 0;
for (int i = 0; i < n; i++)
if (abs(P[i].x - midPoint.x) < d)
strip[j] = P[i], j++;
// Find the closest points in strip. Return the minimum of d and closest
// distance is strip[]
return min(d, stripClosest(strip, j, d) );
}
// The main functin that finds the smallest distance
// This method mainly uses closestUtil()
float closest(Point P[], int n)
{
qsort(P, n, sizeof(Point), compareX);
// Use recursive function closestUtil() to find the smallest distance
return closestUtil(P, n);
}
// Driver program to test above functions
int main()
{
Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};
int n = sizeof(P) / sizeof(P[0]);
printf("The smallest distance is %f ", closest(P, n));
return 0;
}
Output:
Time Complexity Let Time complexity of above algorithm be T(n). Let us assume that
we use a O(nLogn) sorting algorithm. The above algorithm divides all points in two sets
and recursively calls for two sets. After dividing, it finds the strip in O(n) time, sorts the
strip in O(nLogn) time and finally finds the closest points in strip in O(n) time. So T(n)
can expressed as follows
T(n) = 2T(n/2) + O(n) + O(nLogn) + O(n)
T(n) = 2T(n/2) + O(nLogn)
T(n) = T(n x Logn x Logn)
Notes
1) Time complexity can be improved to O(nLogn) by optimizing step 5 of the above algo-
rithm. We will soon be discussing the optimized solution in a separate post.
59
Chapter 8. Closest Pair of Points using Divide and Conquer algorithm
2) The code finds smallest distance. It can be easily modified to find the points with small-
est distance.
3) The code uses quick sort which can be O(n^2) in worst case. To have the upper bound
as O(n (Logn)^2), a O(nLogn) sorting algorithm like merge sort or heap sort can be used
References:
http://www.cs.umd.edu/class/fall2013/cmsc451/Lects/lect10.pdf
http://www.youtube.com/watch?v=vS4Zn1a9KUc
http://www.youtube.com/watch?v=T3T7T8Ym20M
http://en.wikipedia.org/wiki/Closest_pair_of_points_problem
Source
https://www.geeksforgeeks.org/closest-pair-of-points-using-divide-and-conquer-algorithm/
60
Chapter 9
We have discussed a divide and conquer solution for this problem. The time complexity of
the implementation provided in the previous post is O(n (Logn)^2). In this post, we discuss
an implementation with time complexity as O(nLogn).
Following is a recap of the algorithm discussed in the previous post.
1) We sort all points according to x coordinates.
2) Divide all points in two halves.
3) Recursively find the smallest distances in both subarrays.
4) Take the minimum of two smallest distances. Let the minimum be d.
5) Create an array strip[] that stores all points which are at most d distance away from the
middle line dividing the two sets.
6) Find the smallest distance in strip[].
7) Return the minimum of d and the smallest distance calculated in above step 6.
The great thing about the above approach is, if the array strip[] is sorted according to y
coordinate, then we can find the smallest distance in strip[] in O(n) time. In the implemen-
tation discussed in previous post, strip[] was explicitly sorted in every recursive call that
made the time complexity O(n (Logn)^2), assuming that the sorting step takes O(nLogn)
61
Chapter 9. Closest Pair of Points | O(nlogn) Implementation
time.
In this post, we discuss an implementation where the time complexity is O(nLogn). The
idea is to presort all points according to y coordinates. Let the sorted array be Py[]. When
we make recursive calls, we need to divide points of Py[] also according to the vertical line.
We can do that by simply processing every point and comparing its x coordinate with x
coordinate of middle line.
Following is C++ implementation of O(nLogn) approach.
// A divide and conquer program in C++ to find the smallest distance from a
// given set of points.
#include <iostream>
#include <float.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
// A structure to represent a Point in 2D plane
struct Point
{
int x, y;
};
/* Following two functions are needed for library function qsort().
Refer: http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */
// Needed to sort array of points according to X coordinate
int compareX(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->x - p2->x);
}
// Needed to sort array of points according to Y coordinate
int compareY(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->y - p2->y);
}
// A utility function to find the distance between two points
float dist(Point p1, Point p2)
{
return sqrt( (p1.x - p2.x)*(p1.x - p2.x) +
(p1.y - p2.y)*(p1.y - p2.y)
);
}
62
Chapter 9. Closest Pair of Points | O(nlogn) Implementation
// A Brute Force method to return the smallest distance between two points
// in P[] of size n
float bruteForce(Point P[], int n)
{
float min = FLT_MAX;
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
if (dist(P[i], P[j]) < min)
min = dist(P[i], P[j]);
return min;
}
// A utility function to find minimum of two float values
float min(float x, float y)
{
return (x < y)? x : y;
}
// A utility function to find the distance beween the closest points of
// strip of given size. All points in strip[] are sorted accordint to
// y coordinate. They all have an upper bound on minimum distance as d.
// Note that this method seems to be a O(n^2) method, but it's a O(n)
// method as the inner loop runs at most 6 times
float stripClosest(Point strip[], int size, float d)
{
float min = d; // Initialize the minimum distance as d
// Pick all points one by one and try the next points till the difference
// between y coordinates is smaller than d.
// This is a proven fact that this loop runs at most 6 times
for (int i = 0; i < size; ++i)
for (int j = i+1; j < size && (strip[j].y - strip[i].y) < min; ++j)
if (dist(strip[i],strip[j]) < min)
min = dist(strip[i], strip[j]);
return min;
}
// A recursive function to find the smallest distance. The array Px contains
// all points sorted according to x coordinates and Py contains all points
// sorted according to y coordinates
float closestUtil(Point Px[], Point Py[], int n)
{
// If there are 2 or 3 points, then use brute force
if (n <= 3)
return bruteForce(Px, n);
63
Chapter 9. Closest Pair of Points | O(nlogn) Implementation
64
Chapter 9. Closest Pair of Points | O(nlogn) Implementation
Px[i] = P[i];
Py[i] = P[i];
}
qsort(Px, n, sizeof(Point), compareX);
qsort(Py, n, sizeof(Point), compareY);
// Use recursive function closestUtil() to find the smallest distance
return closestUtil(Px, Py, n);
}
// Driver program to test above functions
int main()
{
Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};
int n = sizeof(P) / sizeof(P[0]);
cout << "The smallest distance is " << closest(P, n);
return 0;
}
Output:
Time Complexity:Let Time complexity of above algorithm be T(n). Let us assume that
we use a O(nLogn) sorting algorithm. The above algorithm divides all points in two sets
and recursively calls for two sets. After dividing, it finds the strip in O(n) time. Also, it
takes O(n) time to divide the Py array around the mid vertical line. Finally finds the closest
points in strip in O(n) time. So T(n) can expressed as follows
T(n) = 2T(n/2) + O(n) + O(n) + O(n)
T(n) = 2T(n/2) + O(n)
T(n) = T(nLogn)
References:
http://www.cs.umd.edu/class/fall2013/cmsc451/Lects/lect10.pdf
http://www.youtube.com/watch?v=vS4Zn1a9KUc
http://www.youtube.com/watch?v=T3T7T8Ym20M
http://en.wikipedia.org/wiki/Closest_pair_of_points_problem
Source
https://www.geeksforgeeks.org/closest-pair-of-points-onlogn-implementation/
65
Chapter 10
Input : height[] = [2 1 2 5 1]
Each value of this array corresponds to
the height of stack that is we are given
five stack of coins, where in first stack
2 coins are there then in second stack
1 coin is there and so on.
Output : 4
We can collect all above coins in 4 steps
which are shown in below diagram.
Each step is shown by different color.
66
Chapter 10. Collect all coins in minimum number of steps
We can solve this problem using divide and conquer method. We can see that it is always
beneficial to remove horizontal lines from below. Suppose we are working on stacks from
l index to r index in a recursion step, each time we will choose minimum height, remove
those many horizontal lines after which stack will be broken into two parts, l to minimum
and minimum +1 till r and we will call recursively in those subarrays. Another thing is we
can also collect coins using vertical lines so we will choose minimum between the result of
recursive calls and (r – l) because using (r – l) vertical lines we can always collect all coins.
As each time we are calling each subarray and finding minimum of that, total time
complexity of the solution will be O(N2 )
C++
67
Chapter 10. Collect all coins in minimum number of steps
Java
68
Chapter 10. Collect all coins in minimum number of steps
minStepsRecur(height, m + 1, r, height[m]) +
height[m] - h);
}
// method returns minimum number of step to
// collect coin from stack, with height in
// height[] array
public static int minSteps(int height[], int N)
{
return minStepsRecur(height, 0, N, 0);
}
/* Driver program to test above function */
public static void main(String[] args)
{
int height[] = { 2, 1, 2, 5, 1 };
int N = height.length;
System.out.println(minSteps(height, N));
}
}
// This code is contributed by Arnav Kr. Mandal.
Python 3
69
Chapter 10. Collect all coins in minimum number of steps
# choose minimum from,
# 1) collecting coins using
# all vertical lines (total r - l)
# 2) collecting coins using
# lower horizontal lines and
# recursively on left and
# right segments
return min(r - l,
minStepsRecur(height, l, m, height[m]) +
minStepsRecur(height, m + 1, r, height[m]) +
height[m] - h)
# method returns minimum number
# of step to collect coin from
# stack, with height in height[] array
def minSteps(height, N):
return minStepsRecur(height, 0, N, 0)
# Driver code
height = [ 2, 1, 2, 5, 1 ]
N = len(height)
print(minSteps(height, N))
# This code is contributed
# by ChitraNayal
C#
70
Chapter 10. Collect all coins in minimum number of steps
PHP
<?php
// PHP program to find minimum number of
// steps to collect stack of coins
// recursive method to collect
// coins from height array l to
// r, with height h already
// collected
function minStepsRecur($height, $l,
$r, $h)
71
Chapter 10. Collect all coins in minimum number of steps
{
// if l is more than r,
// no steps needed
if ($l >= $r)
return 0;
// loop over heights to
// get minimum height
// index
$m = $l;
for ($i = $l; $i < $r; $i++)
if ($height[$i] < $height[$m])
$m = $i;
/* choose minimum from,
1) collecting coins using
all vertical lines
(total r - l)
2) collecting coins using
lower horizontal lines
and recursively on left
and right segments */
return min($r - $l,
minStepsRecur($height, $l, $m, $height[$m]) +
minStepsRecur($height, $m + 1, $r, $height[$m]) +
$height[$m] - $h);
}
// method returns minimum number of step to
// collect coin from stack, with height in
// height[] array
function minSteps($height, $N)
{
return minStepsRecur($height, 0, $N, 0);
}
// Driver Code
$height = array(2, 1, 2, 5, 1);
$N = sizeof($height);
echo minSteps($height, $N) ;
// This code is contributed by nitin mittal.
?>
Output:
72
Chapter 10. Collect all coins in minimum number of steps
Source
https://www.geeksforgeeks.org/collect-coins-minimum-number-steps/
73
Chapter 11
Input is an array of points specified by their x and y coordinates. The output is the convex
hull of this set of points.
Examples:
Input : points[] = {(0, 0), (0, 4), (-4, 0), (5, 0),
(0, -6), (1, 0)};
Output : (-4, 0), (5, 0), (0, -6), (0, 4)
Pre-requisite:
Tangents between two convex polygons
Algorithm:
Given the set of points for which we have to find the convex hull. Suppose we know the
convex hull of the left half points and the right half points, then the problem now is to
merge these two convex hulls and determine the convex hull for the complete set.
This can be done by finding the upper and lower tangent to the right and left convex hulls.
This is illustrated here Tangents between two convex polygons
74
Chapter 11. Convex Hull using Divide and Conquer Algorithm
Let the left convex hull be a and the right convex hull be b. Then the lower and upper
tangents are named as 1 and 2 respectively, as shown in the figure.
Then the red outline shows the final convex hull.
Now the problem remains, how to find the convex hull for the left and right half. Now
recursion comes into the picture, we divide the set of points until the number of points in
the set is very small, say 5, and we can find the convex hull for these points by the brute
algorithm. The merging of these halves would result in the convex hull for the complete set
of points.
Note:
We have used the brute algorithm to find the convex hull for a small number of points and
it has a time complexity of . But some people suggest the following, the convex
hull for 3 or fewer points is the complete set of points. This is correct but the problem
comes when we try to merge a left convex hull of 2 points and right convex hull of 3 points,
then the program gets trapped in an infinite loop in some special cases. So, to get rid of
this problem I directly found the convex hull for 5 or fewer points by algorithm,
which is somewhat greater but does not affect the overall complexity of the algorithm.
75
Chapter 11. Convex Hull using Divide and Conquer Algorithm
76
Chapter 11. Convex Hull using Divide and Conquer Algorithm
77
Chapter 11. Convex Hull using Divide and Conquer Algorithm
78
Chapter 11. Convex Hull using Divide and Conquer Algorithm
s.insert(a[i]);
s.insert(a[j]);
}
}
}
vector<pair<int, int>>ret;
for (auto e:s)
ret.push_back(e);
// Sorting the points in the anti-clockwise order
mid = {0, 0};
int n = ret.size();
for (int i=0; i<n; i++)
{
mid.first += ret[i].first;
mid.second += ret[i].second;
ret[i].first *= n;
ret[i].second *= n;
}
sort(ret.begin(), ret.end(), compare);
for (int i=0; i<n; i++)
ret[i] = make_pair(ret[i].first/n, ret[i].second/n);
return ret;
}
// Returns the convex hull for the given set of points
vector<pair<int, int>> divide(vector<pair<int, int>> a)
{
// If the number of points is less than 6 then the
// function uses the brute algorithm to find the
// convex hull
if (a.size() <= 5)
return bruteHull(a);
// left contains the left half points
// right contains the right half points
vector<pair<int, int>>left, right;
for (int i=0; i<a.size()/2; i++)
left.push_back(a[i]);
for (int i=a.size()/2; i<a.size(); i++)
right.push_back(a[i]);
// convex hull for the left and right sets
vector<pair<int, int>>left_hull = divide(left);
vector<pair<int, int>>right_hull = divide(right);
79
Chapter 11. Convex Hull using Divide and Conquer Algorithm
Output:
Convex Hull:
-5 -3
-1 -5
1 -4
0 0
-1 1
Time Complexity: The merging of the left and the right convex hulls take O(n) time
and as we are dividing the points into two equal parts, so the time complexity of the above
algorithm is O(n * log n).
Related Articles :
80
Chapter 11. Convex Hull using Divide and Conquer Algorithm
Source
https://www.geeksforgeeks.org/convex-hull-using-divide-and-conquer-algorithm/
81
Chapter 12
METHOD 1 (Simple)
For each element, count number of elements which are on right side of it and are smaller
than it.
C
#include <bits/stdc++.h>
int getInvCount(int arr[], int n)
{
int inv_count = 0;
for (int i = 0; i < n - 1; i++)
for (int j = i+1; j < n; j++)
if (arr[i] > arr[j])
inv_count++;
return inv_count;
}
/* Driver progra to test above functions */
int main(int argv, char** args)
82
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
{
int arr[] = {1, 20, 6, 4, 5};
int n = sizeof(arr)/sizeof(arr[0]);
printf(" Number of inversions are %d \n", getInvCount(arr, n));
return 0;
}
Java
Python3
83
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
return inv_count
# Driver Code
arr = [1, 20, 6, 4, 5]
n = len(arr)
print("Number of inversions are",
getInvCount(arr, n))
# This code is contributed by Smitha Dinesh Semwal
C#
Output:
84
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
85
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
Implementation:
#include <bits/stdc++.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)
{
86
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
87
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
Java
88
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
89
Chapter 12. Count Inversions in an array | Set 1 (Using Merge Sort)
arr[i] = temp[i];
return inv_count;
}
// Driver method to test the above function
public static void main(String[] args)
{
int arr[] = new int[]{1, 20, 6, 4, 5};
System.out.println("Number of inversions are " + mergeSort(arr, 5));
}
}
Output:
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.
References:
http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08-inversions.pdf
http://www.cp.eng.chula.ac.th/~piak/teaching/algo/algo2008/count-inv.htm
Improved By : Sam007
Source
https://www.geeksforgeeks.org/counting-inversions/
90
Chapter 13
Count all possible walks from a source to a destination with exactly k edges - GeeksforGeeks
Given a directed graph and two vertices ‘u’ and ‘v’ in it, count all possible walks from ‘u’
to ‘v’ with exactly k edges on the walk.
The graph is given as adjacency matrix representation where value of graph[i][j] as 1 indicates
that there is an edge from vertex i to vertex j and a value 0 indicates no edge from i to j.
For example consider the following graph. Let source ‘u’ be vertex 0, destination ‘v’ be 3
and k be 2. The output should be 2 as there are two walk from 0 to 3 with exactly 2 edges.
The walks are {0, 2, 3} and {0, 1, 3}
A simple solution is to start from u, go to all adjacent vertices and recur for adjacent
91
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
vertices with k as k-1, source as adjacent vertex and destination as v. Following is the
implementation of this simple solution.
C++
Java
92
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
import java.util.*;
import java.lang.*;
import java.io.*;
class KPaths
{
static final int V = 4; //Number of vertices
// A naive recursive function to count walks from u
// to v with k edges
int countwalks(int graph[][], int u, int v, int k)
{
// Base cases
if (k == 0 && u == v) return 1;
if (k == 1 && graph[u][v] == 1) return 1;
if (k <= 0) return 0;
// Initialize result
int count = 0;
// Go to all adjacents of u and recur
for (int i = 0; i < V; i++)
if (graph[u][i] == 1) // Check if is adjacent of u
count += countwalks(graph, i, v, k-1);
return count;
}
// Driver method
public static void main (String[] args) throws java.lang.Exception
{
/* Let us create the graph shown in above diagram*/
int graph[][] =new int[][] { {0, 1, 1, 1},
{0, 0, 0, 1},
{0, 0, 0, 1},
{0, 0, 0, 0}
};
int u = 0, v = 3, k = 2;
KPaths p = new KPaths();
System.out.println(p.countwalks(graph, u, v, k));
}
}//Contributed by Aakash Hasija
Python3
93
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
C#
94
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
95
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
}
}
// This code is contributed by nitin mittal.
PHP
<?php
// PHP program to count walks from u
// to v with exactly k edges
// Number of vertices in the graph
$V = 4;
// A naive recursive function to count
// walks from u to v with k edges
function countwalks( $graph, $u, $v, $k)
{
global $V;
// Base cases
if ($k == 0 and $u == $v)
return 1;
if ($k == 1 and $graph[$u][$v])
return 1;
if ($k <= 0)
return 0;
// Initialize result
$count = 0;
// Go to all adjacents of u and recur
for ( $i = 0; $i < $V; $i++)
// Check if is adjacent of u
if ($graph[$u][$i] == 1)
$count += countwalks($graph, $i,
$v, $k - 1);
return $count;
}
// Driver Code
/* Let us create the graph
shown in above diagram*/
$graph = array(array(0, 1, 1, 1),
array(0, 0, 0, 1),
array(0, 0, 0, 1),
96
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
array(0, 0, 0, 0));
$u = 0; $v = 3; $k = 2;
echo countwalks($graph, $u, $v, $k);
// This code is contributed by anuj_67.
?>
Output:
The worst case time complexity of the above function is O(Vk ) where V is the number of
vertices in the given graph. We can simply analyze the time complexity by drawing recursion
tree. The worst occurs for a complete graph. In worst case, every internal node of recursion
tree would have exactly n children.
We can optimize the above solution using Dynamic Programming. The idea is to build
a 3D table where first dimension is source, second dimension is destination, third dimension
is number of edges from source to destination, and the value is count of walks. Like other
Dynamic Programming problems, we fill the 3D table in bottom up manner.
C++
97
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
if (e == 0 && i == j)
count[i][j][e] = 1;
if (e == 1 && graph[i][j])
count[i][j][e] = 1;
// go to adjacent only when number of edges is more than 1
if (e > 1)
{
for (int a = 0; a < V; a++) // adjacent of source i
if (graph[i][a])
count[i][j][e] += count[a][j][e-1];
}
}
}
}
return count[u][v][k];
}
// driver program to test above function
int main()
{
/* Let us create the graph shown in above diagram*/
int graph[V][V] = { {0, 1, 1, 1},
{0, 0, 0, 1},
{0, 0, 0, 1},
{0, 0, 0, 0}
};
int u = 0, v = 3, k = 2;
cout << countwalks(graph, u, v, k);
return 0;
}
Java
98
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
99
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
C#
100
Chapter 13. Count all possible walks from a source to a destination with exactly k edges
count[i,j,e] +=
count[a,j,e-1];
}
}
}
}
return count[u,v,k];
}
// Driver method
public static void Main ()
{
/* Let us create the graph shown in
above diagram*/
int [,]graph = { {0, 1, 1, 1},
{0, 0, 0, 1},
{0, 0, 0, 1},
{0, 0, 0, 0} };
int u = 0, v = 3, k = 2;
Console.WriteLine(
countwalks(graph, u, v, k));
}
}
// This is Code Contributed by anuj_67.
Output:
Time complexity of the above DP based solution is O(V3 K) which is much better than the
naive solution.
We can also use Divide and Conquer to solve the above problem in O(V3 Logk) time.
The count of walks of length k from u to v is the [u][v]’th entry in (graph[V][V])k . We
can calculate power of by doing O(Logk) multiplication by using the divide and conquer
technique to calculate power. A multiplication between two matrices of size V x V takes
O(V3 ) time. Therefore overall time complexity of this method is O(V3 Logk).
Improved By : nitin mittal, vt_m
Source
https://www.geeksforgeeks.org/count-possible-paths-source-destination-exactly-k-edges/
101
Chapter 14
C++
102
Chapter 14. Count number of occurrences (or frequency) in a sorted array
Java
Python3
103
Chapter 14. Count number of occurrences (or frequency) in a sorted array
# occurrences of an element
# Returns number of times x
# occurs in arr[0..n-1]
def countOccurrences(arr, n, x):
res = 0
for i in range(n):
if x == arr[i]:
res += 1
return res
# Driver code
arr = [1, 2, 2, 2, 2, 3, 4, 7 ,8 ,8]
n = len(arr)
x = 2
print (countOccurrences(arr, n, x))
C#
104
Chapter 14. Count number of occurrences (or frequency) in a sorted array
}
// This code is contributed by Sam007
PHP
<?php
// PHP program to count occurrences
// of an element
// Returns number of times x
// occurs in arr[0..n-1]
function countOccurrences($arr, $n, $x)
{
$res = 0;
for ($i = 0; $i < $n; $i++)
if ($x == $arr[$i])
$res++;
return $res;
}
// Driver code
$arr = array(1, 2, 2, 2, 2, 3, 4, 7 ,8 ,8 );
$n = count($arr);
$x = 2;
echo countOccurrences($arr,$n, $x);
// This code is contributed by Sam007
?>
Output :
105
Chapter 14. Count number of occurrences (or frequency) in a sorted array
106
Chapter 14. Count number of occurrences (or frequency) in a sorted array
// Driver code
int main()
{
int arr[] = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
int n = sizeof(arr) / sizeof(arr[0]);
int x = 2;
cout << countOccurrences(arr, n, x);
return 0;
}
Java
107
Chapter 14. Count number of occurrences (or frequency) in a sorted array
108
Chapter 14. Count number of occurrences (or frequency) in a sorted array
Python 3
109
Chapter 14. Count number of occurrences (or frequency) in a sorted array
count += 1
left -= 1
# Count elements on
# right side.
right = ind + 1;
while (right < n and
arr[right] == x):
count += 1
right += 1
return count
# Driver code
arr = [ 1, 2, 2, 2, 2,
3, 4, 7, 8, 8 ]
n = len(arr)
x = 2
print(countOccurrences(arr, n, x))
# This code is contributed
# by ChitraNayal
C#
// C# program to count
// occurrences of an element
using System;
class GFG
{
// A recursive binary search
// function. It returns location
// of x in given array arr[l..r]
// is present, otherwise -1
static int binarySearch(int[] arr, int l,
int r, int x)
{
if (r < l)
return -1;
int mid = l + (r - l) / 2;
// If the element is present
// at the middle itself
if (arr[mid] == x)
return mid;
110
Chapter 14. Count number of occurrences (or frequency) in a sorted array
// If element is smaller than
// mid, then it can only be
// present in left subarray
if (arr[mid] > x)
return binarySearch(arr, l,
mid - 1, x);
// Else the element
// can only be present
// in right subarray
return binarySearch(arr, mid + 1,
r, x);
}
// Returns number of times x
// occurs in arr[0..n-1]
static int countOccurrences(int[] arr,
int n, int x)
{
int ind = binarySearch(arr, 0,
n - 1, x);
// If element is not present
if (ind == -1)
return 0;
// Count elements on left side.
int count = 1;
int left = ind - 1;
while (left >= 0 &&
arr[left] == x)
{
count++;
left--;
}
// Count elements on right side.
int right = ind + 1;
while (right < n &&
arr[right] == x)
{
count++;
right++;
}
return count;
}
111
Chapter 14. Count number of occurrences (or frequency) in a sorted array
// Driver code
public static void Main()
{
int[] arr = {1, 2, 2, 2, 2,
3, 4, 7, 8, 8};
int n = arr.Length;
int x = 2;
Console.Write(countOccurrences(arr, n, x));
}
}
// This code is contributed
// by ChitraNayal
PHP
<?php
// PHP program to count
// occurrences of an element
// A recursive binary search
// function. It returns location
// of x in given array arr[l..r]
// is present, otherwise -1
function binarySearch(&$arr, $l,
$r, $x)
{
if ($r < $l)
return -1;
$mid = $l + ($r - $l) / 2;
// If the element is present
// at the middle itself
if ($arr[$mid] == $x)
return $mid;
// If element is smaller than
// mid, then it can only be
// present in left subarray
if ($arr[$mid] > $x)
return binarySearch($arr, $l,
$mid - 1, $x);
// Else the element
// can only be present
112
Chapter 14. Count number of occurrences (or frequency) in a sorted array
113
Chapter 14. Count number of occurrences (or frequency) in a sorted array
Output :
114
Chapter 14. Count number of occurrences (or frequency) in a sorted array
# include <stdio.h>
/* if x is present in arr[] then returns
the index of FIRST occurrence
of x in arr[0..n-1], otherwise returns -1 */
int first(int arr[], int low, int high, int x, int n)
{
if(high >= low)
{
int mid = (low + high)/2; /*low + (high - low)/2;*/
if( ( mid == 0 || x > arr[mid-1]) && arr[mid] == x)
return mid;
else if(x > arr[mid])
return first(arr, (mid + 1), high, x, n);
else
return first(arr, low, (mid -1), x, n);
}
return -1;
}
/* if x is present in arr[] then returns the
index of LAST occurrence of x in arr[0..n-1],
otherwise returns -1 */
int last(int arr[], int low, int high, int x, int n)
{
if (high >= low)
{
int mid = (low + high)/2; /*low + (high - low)/2;*/
if( ( mid == n-1 || x < arr[mid+1]) && arr[mid] == x )
return mid;
else if(x < arr[mid])
return last(arr, low, (mid -1), x, n);
else
return last(arr, (mid + 1), high, x, n);
}
return -1;
}
/* if x is present in arr[] then returns the count
of occurrences of x, otherwise returns -1. */
int count(int arr[], int x, int n)
115
Chapter 14. Count number of occurrences (or frequency) in a sorted array
{
int i; // index of first occurrence of x in arr[0..n-1]
int j; // index of last occurrence of x in arr[0..n-1]
/* get the index of first occurrence of x */
i = first(arr, 0, n-1, x, n);
/* If x doesn't exist in arr[] then return -1 */
if(i == -1)
return i;
/* Else get the index of last occurrence of x.
Note that we are only looking in the subarray
after first occurrence */
j = last(arr, i, n-1, x, n);
/* return count */
return j-i+1;
}
/* driver program to test above functions */
int main()
{
int arr[] = {1, 2, 2, 3, 3, 3, 3};
int x = 3; // Element to be counted in arr[]
int n = sizeof(arr)/sizeof(arr[0]);
int c = count(arr, x, n);
printf(" %d occurs %d times ", x, c);
getchar();
return 0;
}
Java
116
Chapter 14. Count number of occurrences (or frequency) in a sorted array
int j;
/* get the index of first occurrence of x */
i = first(arr, 0, n-1, x, n);
/* If x doesn't exist in arr[] then return -1 */
if(i == -1)
return i;
/* Else get the index of last occurrence of x.
Note that we are only looking in the
subarray after first occurrence */
j = last(arr, i, n-1, x, n);
/* return count */
return j-i+1;
}
/* if x is present in arr[] then returns the
index of FIRST occurrence of x in arr[0..n-1],
otherwise returns -1 */
static int first(int arr[], int low, int high, int x, int n)
{
if(high >= low)
{
/*low + (high - low)/2;*/
int mid = (low + high)/2;
if( ( mid == 0 || x > arr[mid-1]) && arr[mid] == x)
return mid;
else if(x > arr[mid])
return first(arr, (mid + 1), high, x, n);
else
return first(arr, low, (mid -1), x, n);
}
return -1;
}
/* if x is present in arr[] then returns the
index of LAST occurrence of x in arr[0..n-1],
otherwise returns -1 */
static int last(int arr[], int low, int high, int x, int n)
{
if(high >= low)
{
/*low + (high - low)/2;*/
int mid = (low + high)/2;
if( ( mid == n-1 || x < arr[mid+1]) && arr[mid] == x )
return mid;
117
Chapter 14. Count number of occurrences (or frequency) in a sorted array
Python3
118
Chapter 14. Count number of occurrences (or frequency) in a sorted array
C#
119
Chapter 14. Count number of occurrences (or frequency) in a sorted array
/* if x is present in arr[] then returns
the count of occurrences of x,
otherwise returns -1. */
static int count(int []arr, int x, int n)
{
// index of first occurrence of x in arr[0..n-1]
int i;
// index of last occurrence of x in arr[0..n-1]
int j;
/* get the index of first occurrence of x */
i = first(arr, 0, n-1, x, n);
/* If x doesn't exist in arr[] then return -1 */
if(i == -1)
return i;
/* Else get the index of last occurrence of x.
Note that we are only looking in the
subarray after first occurrence */
j = last(arr, i, n-1, x, n);
/* return count */
return j-i+1;
}
/* if x is present in arr[] then returns the
index of FIRST occurrence of x in arr[0..n-1],
otherwise returns -1 */
static int first(int []arr, int low, int high,
int x, int n)
{
if(high >= low)
{
/*low + (high - low)/2;*/
int mid = (low + high)/2;
if( ( mid == 0 || x > arr[mid-1])
&& arr[mid] == x)
return mid;
else if(x > arr[mid])
return first(arr, (mid + 1), high, x, n);
else
return first(arr, low, (mid -1), x, n);
}
return -1;
}
120
Chapter 14. Count number of occurrences (or frequency) in a sorted array
/* if x is present in arr[] then returns the
index of LAST occurrence of x in arr[0..n-1],
otherwise returns -1 */
static int last(int []arr, int low,
int high, int x, int n)
{
if(high >= low)
{
/*low + (high - low)/2;*/
int mid = (low + high)/2;
if( ( mid == n-1 || x < arr[mid+1])
&& arr[mid] == x )
return mid;
else if(x < arr[mid])
return last(arr, low, (mid -1), x, n);
else
return last(arr, (mid + 1), high, x, n);
}
return -1;
}
public static void Main()
{
int []arr = {1, 2, 2, 3, 3, 3, 3};
// Element to be counted in arr[]
int x = 3;
int n = arr.Length;
int c = count(arr, x, n);
Console.Write(x + " occurs " + c + " times");
}
}
// This code is contributed by Sam007
Output:
3 occurs 4 times
121
Chapter 14. Count number of occurrences (or frequency) in a sorted array
Source
https://www.geeksforgeeks.org/count-number-of-occurrences-or-frequency-in-a-sorted-array/
122
Chapter 15
Cut all the rods with some length such that the sum of cut-off length is maximized - Geeks-
forGeeks
Given N rods of different lengths. The task is to cut all the rods with some maximum integer
height ‘h’ such that sum of cut-off lengths of the rod is maximized and must be greater than
M. Print -1 if no such cut is possible.
Note: A rod cannot be cut also.
Examples:
Approach:
123
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
124
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
// returning the maximum cut off length
return low - 1;
}
// Driver Function
int main()
{
int n1 = 7;
int n2 = 8;
int adj[] = { 1, 2, 3, 4, 5, 7, 6 };
// Sorting the array in ascending order
sort(adj, adj + n1);
// Calling the binarySearch Function
cout << binarySearch(adj, n2, n1);
}
Java
125
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
126
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
// Calling the binarySearch Function
System.out.println(binarySearch(adj, n2, n1));
}
}
// This code is contributed
// by Arnab Kundu
Python3
127
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
f = 1
low = mid + 1
break
# If flag variable is
# not set. Change high
if f == 0 :
high = mid
# returning the maximum
# cut off length
return low - 1
# Driver code
if __name__ == "__main__" :
n1 = 7
n2 = 8
# adj = [1,2,3,3]
adj = [ 1, 2, 3, 4, 5, 7, 6]
# Sorting the array
# in ascending order
adj.sort()
# Calling the binarySearch Function
print(binarySearch(adj, n2, n1))
# This code is contributed
# by ANKITRAI1
C#
128
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
int length)
{
int low = 0;
int high = adj[length - 1];
while (low < high)
{
// f is the flag varibale
// sum is for the total
// length cutoff
int f = 0, sum = 0;
int mid = (low + high) / 2;
// Loop from higer to lower
// for optimization
for (int i = length - 1;
i >= 0; i--)
{
// Only if length is greater
// than cut-off length
if (adj[i] > mid)
{
sum = sum + adj[i] - mid;
}
// When total cut off length
// becomes greater than
// desired cut off length
if (sum >= target)
{
f = 1;
low = mid + 1;
break;
}
}
// If flag variable is
// not set Change high
if (f == 0)
high = mid;
}
// returning the maximum
// cut off length
return low - 1;
}
129
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
// Driver Code
public static void Main()
{
int n1 = 7;
int n2 = 8;
int []adj = {1, 2, 3, 4, 5, 7, 6};
// Sorting the array
// in ascending order
Array.Sort(adj);
// Calling the binarySearch Function
Console.WriteLine(binarySearch(adj, n2, n1));
}
}
// This code is contributed
// by Subhadeep Gupta
PHP
= 0; $i–)
{
// Only if length is greater
// than cut-off length
if ($adj[$i] > $mid)
{
$sum = $sum + $adj[$i] – $mid;
}
// When total cut off length becomes
// greater than desired cut off length
if ($sum >= $target)
{
$f = 1;
$low = $mid + 1;
break;
}
}
// If flag variable is not
// set Change high
if ($f == 0)
$high = $mid;
}
// returning the maximum cut off length
130
Chapter 15. Cut all the rods with some length such that the sum of cut-off length is
maximized
return $low – 1;
}
// Driver Code
$n1 = 7;
$n2 = 8;
$adj = array( 1, 2, 3, 4, 5, 7, 6 );
// Sorting the array in ascending order
sort($adj);
// Calling the binarySearch Function
echo (int)binarySearch($adj, $n2, $n1);
// This code is contributed by ChitraNayal
?>
Output:
Source
https://www.geeksforgeeks.org/cut-all-the-rods-with-some-length-such-that-the-sum-of-cut-off-length-is-maximized
131
Chapter 16
132
Chapter 16. Decrease and Conquer
1. Decrease by a constant
2. Decrease by a constant factor
3. Variable size decrease
• Insertion sort
• Graph search algorithms: DFS, BFS
• Topological sorting
• Algorithms for generating permutations, subsets
• Binary search
• Fake-coin problems
• Russian peasant multiplication
There may be a case that problem can be solved by decrease-by-constant as well as decrease-
by-factor variations, but the implementations can be either recursive or iterative. The
iterative implementations may require more coding effort, however they avoid the overload
that accompanies recursion.
Reference :
Anany Levitin
Decrease and conquer
Source
https://www.geeksforgeeks.org/decrease-and-conquer/
133
Chapter 17
134
Chapter 17. Distinct elements in subarray using Mo’s Algorithm
1 8
output : 5
4
6
7
1. Sort all queries in a way that queries with L values from 0 to are
2. Initialize an array freq[] of size with 0 . freq[] array keep count of frequencies
of all the elements in lying in a given range.
3. Process all queries one by one in a way that every query uses number of different
elements and frequency array computed in previous query and stores the result in
structure.
Sort the queries in the same order as they were provided earlier and print their stored results
Adding elements()
Removing elements()
Note : In this algorithm, in step 2, index variable for R change at most O(n * )
times throughout the run and same for L changes its value at most O(m * ) times.
All these bounds are possible only because sorted queries first in blocks of size.
135
Chapter 17. Distinct elements in subarray using Mo’s Algorithm
136
Chapter 17. Distinct elements in subarray using Mo’s Algorithm
137
Chapter 17. Distinct elements in subarray using Mo’s Algorithm
currL--;
}
while (currR <= R) {
freq[a[currR]]++;
// include a element if it occurs first time
if (freq[a[currR]] == 1)
curr_Diff_elements++;
currR++;
}
// Remove elements of previous range. For example
// when previous range is [0, 10] and current range
// is [3, 8], then a[9] and a[10] are subtracted
// Note:- Basically for a previous query L to R
// currL is L and currR is R+1. So during removal
// of currR remove currR-1 because currR was
// never included
while (currR > R + 1) {
// element a[currL] is removed
freq[a[currR - 1]]--;
// if ocurrence of a number is reduced
// to zero remove it from list of
// different elements
if (freq[a[currR - 1]] == 0)
curr_Diff_elements--;
currR--;
}
q[i].result = curr_Diff_elements;
}
}
// print the result of all range queries in
// initial order of queries
void printResults(Query q[], int m)
{
sort(q, q + m, compare1);
for (int i = 0; i < m; i++) {
cout << "Number of different elements" <<
" in range " << q[i].L << " to "
<< q[i].R << " are " << q[i].result << endl;
}
}
138
Chapter 17. Distinct elements in subarray using Mo’s Algorithm
// Driver program
int main()
{
int a[] = { 1, 1, 2, 1, 3, 4, 5, 2, 8 };
int n = sizeof(a) / sizeof(a[0]);
Query q[] = { { 0, 4, 0, 0 }, { 1, 3, 1, 0 },
{ 2, 4, 2, 0 } };
int m = sizeof(q) / sizeof(q[0]);
queryResults(a, n, q, m);
printResults(q, m);
return 0;
}
Output:
Source
https://www.geeksforgeeks.org/distinct-elements-subarray-using-mos-algorithm/
139
Chapter 18
140
Chapter 18. Divide and Conquer Algorithm | Introduction
Source
https://www.geeksforgeeks.org/divide-and-conquer-algorithm-introduction/
141
Chapter 19
142
Chapter 19. Divide and Conquer | Set 5 (Strassen’s Matrix Multiplication)
diagram.
2) Calculate following values recursively. ae + bg, af + bh, ce + dg and cf + dh.
In the above method, we do 8 multiplications for matrices of size N/2 x N/2 and 4 additions.
Addition of two matrices takes O(N2 ) time. So the time complexity can be written as
Simple Divide and Conquer also leads to O(N3 ), can there be a better way?
In the above divide and conquer method, the main component for high time complexity is
8 recursive calls. The idea of Strassen’s method is to reduce the number of recursive
calls to 7. Strassen’s method is similar to above simple divide and conquer method in the
sense that this method also divide matrices to sub-matrices of size N/2 x N/2 as shown in
the above diagram, but in Strassen’s method, the four sub-matrices of result are calculated
using following formulae.
143
Chapter 19. Divide and Conquer | Set 5 (Strassen’s Matrix Multiplication)
Generally Strassen’s Method is not preferred for practical applications for following reasons.
1) The constants used in Strassen’s method are high and for a typical application Naive
method works better.
2) For Sparse matrices, there are better methods especially designed for them.
3) The submatrices in recursion take extra space.
4) Because of the limited precision of computer arithmetic on noninteger values, larger
errors accumulate in Strassen’s algorithm than in Naive Method (Source: CLRS Book)
144
Chapter 19. Divide and Conquer | Set 5 (Strassen’s Matrix Multiplication)
Source
https://www.geeksforgeeks.org/strassens-matrix-multiplication/
145
Chapter 20
Dynamic Programming vs
Divide-and-Conquer
The Problem
When I started to learn algorithms it was hard for me to understand the main idea of
dynamic programming (DP) and how it is different from divide-and-conquer (DC) approach.
When it gets to comparing those two paradigms usually Fibonacci function comes to the
rescue as great example. But when we’re trying to solve the same problem using both DP
and DC approaches to explain each of them, it feels for me like we may lose valuable detail
that might help to catch the difference faster. And these detail tells us that each technique
serves best for different types of problems.
I’m still in the process of understanding DP and DC difference and I can’t say that I’ve fully
grasped the concepts so far. But I hope this article will shed some extra light and help you
to do another step of learning such valuable algorithm paradigms as dynamic programming
and divide-and-conquer.
As I see it for now I can say that dynamic programming is an extension of divide and conquer
paradigm.
I would not treat them as something completely different. Because they both work by
recursively breaking down a problem into two or more sub-problems of the same or related
146
Chapter 20. Dynamic Programming vs Divide-and-Conquer
type, until these become simple enough to be solved directly. The solutions to the sub-
problems are then combined to give a solution to the original problem.
So why do we still have different paradigm names then and why I called dynamic program-
ming an extension. It is because dynamic programming approach may be applied to the
problem only if the problem has certain restrictions or prerequisites. And after that dy-
namic programming extends divide and conquer approach with memoization or tabulation
technique.
Let’s go step by step…
As we’ve just discovered there are two key attributes that divide and conquer problem must
have in order for dynamic programming to be applicable:
Once these two conditions are met we can say that this divide and conquer problem may
be solved using dynamic programming approach.
Dynamic programming approach extends divide and conquer approach with two techniques
(memoization and tabulation) that both have a purpose of storing and re-using sub-problems
solutions that may drastically improve performance. For example naive recursive implemen-
tation of Fibonacci function has time complexity of O(2^n) where DP solution doing the
same with only O(n) time.
Memoization (top-down cache filling) refers to the technique of caching and reusing previ-
ously computed results. The memoized fib function would thus look like this:
memFib(n) {
if (mem[n] is undefined)
if (n < 2) result = n
else result = memFib(n-2) + memFib(n-1)
mem[n] = result
return mem[n]
}
Tabulation (bottom-up cache filling) is similar but focuses on filling the entries of the cache.
Computing the values in the cache is easiest done iteratively. The tabulation version of fib
would look like this:
147
Chapter 20. Dynamic Programming vs Divide-and-Conquer
Figure 20.1:
tabFib(n) {
mem[0] = 0
mem[1] = 1
for i = 2...n
mem[i] = mem[i-2] + mem[i-1]
return mem[n]
}
You may read more about memoization and tabulation comparison here.
The main idea you should grasp here is that because our divide and conquer problem has
overlapping sub-problems the caching of sub-problem solutions becomes possible and thus
memoization/tabulation step up onto the scene.
Since we’re now familiar with DP prerequisites and its methodologies we’re ready to put all
that was mentioned above into one picture.
Let’s go and try to solve some problems using DP and DC approaches to make this illustra-
tion more clear.
Binary search algorithm, also known as half-interval search, is a search algorithm that finds
148
Chapter 20. Dynamic Programming vs Divide-and-Conquer
the position of a target value within a sorted array. Binary search compares the target value
to the middle element of the array; if they are unequal, the half in which the target cannot
lie is eliminated and the search continues on the remaining half until the target value is
found. If the search ends with the remaining half being empty, the target is not in the array.
Example
Here is a visualization of the binary search algorithm where 4 is the target value.
Let’s draw the same logic but in form of decision tree.
You may clearly see here a divide and conquer principle of solving the problem. We’re
iteratively breaking the original array into sub-arrays and trying to find required element
in there.
Can we apply dynamic programming to it? No. It is because there are no overlapping sub-
problems. Every time we split the array into completely independent parts. And according
to divide and conquer prerequisites/restrictions the sub-problems must be overlapped some-
how.
Normally every time you draw a decision tree and it is actually a tree (and not a decision
graph) it would mean that you don’t have overlapping sub-problems and this is not dynamic
programming problem.
The Code
Here you may find complete source code of binary search function with test cases and
explanations.
149
Chapter 20. Dynamic Programming vs Divide-and-Conquer
Figure 20.2:
150
Chapter 20. Dynamic Programming vs Divide-and-Conquer
Figure 20.3:
151
Chapter 20. Dynamic Programming vs Divide-and-Conquer
Figure 20.4:
Normally when it comes to dynamic programming examples the Fibonacci number algorithm
is being taken by default. But let’s take a little bit more complex algorithm to have some
kind of variety that should help us to grasp the concept.
Minimum Edit Distance (or Levenshtein Distance) is a string metric for measuring the differ-
ence between two sequences. Informally, the Levenshtein distance between two words is the
minimum number of single-character edits (insertions, deletions or substitutions) required
to change one word into the other.
Example
For example, the Levenshtein distance between “kitten” and “sitting” is 3, since the following
three edits change one into the other, and there is no way to do it with fewer than three
edits:
Applications
This has a wide range of applications, for instance, spell checkers, correction systems for
optical character recognition, fuzzy string searching, and software to assist natural language
translation based on translation memory.
Mathematical Definition
Mathematically, the Levenshtein distance between two strings a, b (of length |a| and |b|
respectively) is given by function lev(|a|, |b|) where
Note that the first element in the minimum corresponds to deletion (from a to b), the second
to insertion and the third to match or mismatch, depending on whether the respective
symbols are the same.
Explanation
Ok, let’s try to figure out what that formula is talking about. Let’s take a simple example of
finding minimum edit distance between strings ME and MY. Intuitively you already know
that minimum edit distance here is 1 operation and this operation is “replace E with Y”. But
let’s try to formalize it in a form of the algorithm in order to be able to do more complex
examples like transforming Saturday into Sunday.
152
Chapter 20. Dynamic Programming vs Divide-and-Conquer
Figure 20.5: Simple example of finding minimum edit distance between ME and MY strings
To apply the formula to ME>MY transformation we need to know minimum edit distances
of ME>M, M>MY and M>M transformations in prior. Then we will need to pick the
minimum one and add +1 operation to transform last letters E?Y.
So we can already see here a recursive nature of the solution: minimum edit distance of
ME>MY transformation is being calculated based on three previously possible transforma-
tions. Thus we may say that this is divide and conquer algorithm.
To explain this further let’s draw the following matrix.
Cell (0, 1) contains red number 1. It means that we need 1 operation to transform M to
empty string: delete M. This is why this number is red.
Cell (0, 2) contains red number 2. It means that we need 2 operations to transform ME to
empty string: delete E, delete M.
Cell (1, 0) contains green number 1. It means that we need 1 operation to transform empty
string to M: insert M. This is why this number is green.
Cell (2, 0) contains green number 2. It means that we need 2 operations to transform empty
string to MY: insert Y, insert M.
Cell (1, 1) contains number 0. It means that it costs nothing to transform M to M.
Cell (1, 2) contains red number 1. It means that we need 1 operation to transform ME to
M: delete E.
And so on…
This looks easy for such small matrix as ours (it is only 3×3). But how we could calculate all
those numbers for bigger matrices (let’s say 9×7 one, for Saturday>Sunday transformation)?
The good news is that according to the formula you only need three adjacent cells (i-1, j),
(i-1, j-1), and (i, j-1) to calculate the number for current cell (i, j) . All we need to do is to
153
Chapter 20. Dynamic Programming vs Divide-and-Conquer
Figure 20.7: Decision graph for minimum edit distance with overlapping sub-problems
find the minimum of those three cells and then add +1 in case if we have different letters
in i-s row and j-s column
So once again you may clearly see the recursive nature of the problem.
Ok we’ve just found out that we’re dealing with divide and conquer problem here. But can
we apply dynamic programming approach to it? Does this problem satisfies our overlapping
sub-problems and optimal substructure restrictions? Yes. Let’s see it from decision graph.
First of all this is not a decision tree. It is a decision graph. You may see a number of
overlapping subproblems on the picture that are marked with red. Also there is no way to
reduce the number of operations and make it less then a minimum of those three adjacent
cells from the formula.
Also you may notice that each cell number in the matrix is being calculated based on
previous ones. Thus the tabulation technique (filling the cache in bottom-up direction) is
being applied here. You’ll see it in code example below.
Applying this principles further we may solve more complicated cases like with Saturday >
154
Chapter 20. Dynamic Programming vs Divide-and-Conquer
Sunday transformation.
The Code
Here you may find complete source code of minimum edit distance function with test cases
and explanations.
function levenshteinDistance(a, b) {
const distanceMatrix = Array(b.length + 1)
.fill(null)
.map(
() => Array(a.length + 1).fill(null)
);
155
Chapter 20. Dynamic Programming vs Divide-and-Conquer
distanceMatrix[j][i] = Math.min(
distanceMatrix[j][i - 1] + 1, // deletion
distanceMatrix[j - 1][i] + 1, // insertion
distanceMatrix[j - 1][i - 1] + indicator, // substitution
);
}
}
return distanceMatrix[b.length][a.length];
}
Conclusion
In this article we have compared two algorithmic approaches such as dynamic programming
and divide-and-conquer. We’ve found out that dynamic programing is based on divide and
conquer principle and may be applied only if the problem has overlapping sub-problems
and optimal substructure (like in Levenshtein distance case). Dynamic programming then
is using memoization or tabulation technique to store solutions of overlapping sub-problems
for later usage.
I hope this article hasn’t brought you more confusion but rather shed some light on these
two important algorithmic concepts! �
You may find more examples of divide and conquer and dynamic programming problems
with explanations, comments and test cases in JavaScript Algorithms and Data Structures
repository.
Happy coding!
Source
https://www.geeksforgeeks.org/dynamic-programming-vs-divide-and-conquer/
156
Chapter 21
157
Chapter 21. Easy way to remember Strassen’s Matrix Equation
• Write P1 = A; P2 = H; P3 = E; P4 = D
• For P5 we will use Diagonal Rule i.e.
(Sum the Diagonal Elements Of Matrix X ) * (Sum the Diagonal Elements Of Matrix
Y ), we get
P5 = (A + D)* (E + H)
• For P6 we will use Last CR Rule i.e. Last Column of X and Last Row of Y and
remember that Row+ and Column- so i.e. (B – D) * (G + H), we get
P6 = (B – D) * (G + H)
• For P7 we will use First CR Rule i.e. First Column of X and First Row of Y and
remember that Row+ and Column- so i.e. (A – C) * (E + F), we get
P6 = (A – C) * (E + F)
158
Chapter 21. Easy way to remember Strassen’s Matrix Equation
• Come Back to P1 : we have A there and it’s adjacent element in Y Matrix is E, since
Y is Column Matrix so we select a column in Y such that E won’t come, we find F H
Column, so multiply A with (F – H)
So, finally P1 = A * (F – H)
• Come Back to P2 : we have H there and it’s adjacent element in X Matrix is D, since
X is Row Matrix so we select a Row in X such that D won’t come, we find A B Column,
so multiply H with (A + B)
So, finally P2 = H * (A + B)
• Come Back to P3 : we have E there and it’s adjacent element in X Matrix is A, since X
is Row Matrix so we select a Row in X such that A won’t come, we find C D Column,
so multiply E with (C + D)
So, finally P3 = E * (C + D)
• Come Back to P4 : we have D there and it’s adjacent element in Y Matrix is H, since
Y is Column Matrix so we select a column in Y such that H won’t come, we find G E
Column, so multiply D with (G – E)
So, finally P4 = D * (G – E)
• Remember Counting : Write P1 + P2 at C2
• Write P3 + P4 at its diagonal Position i.e. at C3
• Write P4 + P5 + P6 at 1st position and subtract P2 i.e. C1 = P4 + P5 + P6 – P2
• Write odd values at last Position with alternating – and + sign i.e. P1 P3 P5 P7
becomes
C4 = P1 – P3 + P5 – P7
Improved By : BhavayAnand
Source
https://www.geeksforgeeks.org/easy-way-remember-strassens-matrix-equation/
159
Chapter 22
an O( ) naive approach to solve this problem. here. This approach uses the coefficient
form of the polynomial to calculate the product.
Input :
A[] = {9, -10, 7, 6}
B[] = {-5, 4, 0, -2}
Output :
yes
160
Chapter 22. Fast Fourier Transformation for poynomial multiplication
Idea is to represent polynomial in point-value form and then compute the product. A point-
value representation of a polynomial A(x) of degree-bound n is a set of n point-value pairs
is{ (x0, y0), (x1, y1), …, (xn-1, yn-1)} such that all of the xi are distinct and yi = A(xi) for
i = 0, 1, …, n-1.
Example
xi -- 0, 1, 2, 3
A(xi) -- 1, 0, 5, 22
Point-value representation of above polynomial is { (0, 1), (1, 0), (2, 5), (3, 22) }. Using
Horner’s method, (discussed here), n-point evaluation takes time O( ). It’s just
So far we discussed,
.
This idea still solves the problem in O( ) time complexity. We can use any points we
want as evaluation points, but by choosing the evaluation points carefully, we can convert
between representations in only O(n log n) time. If we choose “complex roots of unity” as
the evaluation points, we can produce a point-value representation by taking the discrete
Fourier transform (DFT) of a coefficient vector. We can perform the inverse operation,
interpolation, by taking the “inverse DFT” of point-value pairs, yielding a coefficient vector.
161
Chapter 22. Fast Fourier Transformation for poynomial multiplication
Fast Fourier Transform (FFT) can perform DFT and inverse DFT in time O(nlogn).
DFT
Algorithm
1. Add n higher-order zero coefficients to A(x) and B(x)
2. Evaluate A(x) and B(x) using FFT for 2n points
3. Pointwise multiplication of point-value forms
4. Interpolate C(x) using FFT to compute inverse DFT
Recursive_FFT(a){
n = length(a) // a is the input coefficient vector
if n = 1
then return a
162
Chapter 22. Fast Fourier Transformation for poynomial multiplication
w = 1
for k = 0 to n/2 - 1
since,
Thus, the vector y returned by Recursive-FFT is indeed the DFT of the input
vector a.
163
Chapter 22. Fast Fourier Transformation for poynomial multiplication
#include <bits/stdc++.h>
using namespace std;
// For storing complex values of nth roots
// of unity we use complex<double>
typedef complex<double> cd;
// Recursive function of FFT
vector<cd> fft(vector<cd>& a)
{
int n = a.size();
// if input contains just one element
if (n == 1)
return vector<cd>(1, a[0]);
// For storing n complex nth roots of unity
vector<cd> w(n);
for (int i = 0; i < n; i++) {
double alpha = 2 * M_PI * i / n;
w[i] = cd(cos(alpha), sin(alpha));
}
vector<cd> A0(n / 2), A1(n / 2);
for (int i = 0; i < n / 2; i++) {
// even indexed coefficients
A0[i] = a[i * 2];
// odd indexed coefficients
A1[i] = a[i * 2 + 1];
}
// Recursive call for even indexed coefficients
vector<cd> y0 = fft(A0);
// Recursive call for odd indexed coefficients
vector<cd> y1 = fft(A1);
// for storing values of y0, y1, y2, ..., yn-1.
vector<cd> y(n);
for (int k = 0; k < n / 2; k++) {
y[k] = y0[k] + w[k] * y1[k];
y[k + n / 2] = y0[k] - w[k] * y1[k];
}
return y;
}
164
Chapter 22. Fast Fourier Transformation for poynomial multiplication
// Driver code
int main()
{
vector<cd> a{1, 2, 3, 4};
vector<cd> b = fft(a);
for (int i = 0; i < 4; i++)
cout << b[i] << endl;
return 0;
}
Input: 1 2 3 4
Output:
(10, 0)
(-2, -2)
(-2, 0)
(-2, 2)
Interpolation
Switch the roles of a and y.
Replace wn by wn^-1.
Divide each element of the result by n.
Time Complexity : O(nlogn).
Source
https://www.geeksforgeeks.org/fast-fourier-transformation-poynomial-multiplication/
165
Chapter 23
Now you are given n, and you have to find out nth term using above formula.
Examples:
Input : n = 2
Output : 5
Input : n = 3
Output :13
Prerequisite :
Basic Approach:This problem can be solved by simply just iterating over the n terms.
Every time you find a term, using this term find next one and so on. But time complexity
of this problem is of order O(n).
Optimized Approach
All such problem where a term is a function of other terms in linear fashion. Then these
can be solved using Matrix (Please refer : Matrix Exponentiation). First we make transfor-
mation matrix and then just use matrix exponentiation to find Nth term.
166
Chapter 23. Find Nth term (A matrix exponentiation example)
167
Chapter 23. Find Nth term (A matrix exponentiation example)
{
if (n <= 1)
return 1;
// This power function returns first row of
// {Transformation Matrix}^n-1*Initial Vector
n--;
// This is an identity matrix.
ll res[2][2] = { 1, 0, 0, 1 };
// this is Transformation matrix.
ll tMat[2][2] = { 2, 3, 1, 0 };
// Matrix exponentiation to calculate power of {tMat}^n-1
// store res in "res" matrix.
while (n) {
if (n & 1) {
ll tmp[2][2];
tmp[0][0] = (res[0][0] * tMat[0][0] +
res[0][1] * tMat[1][0]) % MOD;
tmp[0][1] = (res[0][0] * tMat[0][1] +
res[0][1] * tMat[1][1]) % MOD;
tmp[1][0] = (res[1][0] * tMat[0][0] +
res[1][1] * tMat[1][0]) % MOD;
tmp[1][1] = (res[1][0] * tMat[0][1] +
res[1][1] * tMat[1][1]) % MOD;
res[0][0] = tmp[0][0];
res[0][1] = tmp[0][1];
res[1][0] = tmp[1][0];
res[1][1] = tmp[1][1];
}
n = n / 2;
ll tmp[2][2];
tmp[0][0] = (tMat[0][0] * tMat[0][0] +
tMat[0][1] * tMat[1][0]) % MOD;
tmp[0][1] = (tMat[0][0] * tMat[0][1] +
tMat[0][1] * tMat[1][1]) % MOD;
tmp[1][0] = (tMat[1][0] * tMat[0][0] +
tMat[1][1] * tMat[1][0]) % MOD;
tmp[1][1] = (tMat[1][0] * tMat[0][1] +
tMat[1][1] * tMat[1][1]) % MOD;
tMat[0][0] = tmp[0][0];
tMat[0][1] = tmp[0][1];
tMat[1][0] = tmp[1][0];
tMat[1][1] = tmp[1][1];
}
168
Chapter 23. Find Nth term (A matrix exponentiation example)
// res store {Transformation matrix}^n-1
// hence will be first row of res*Initial Vector.
return (res[0][0] * 1 + res[0][1] * 1) % MOD;
}
// Driver code
int main()
{
ll n = 3;
cout << power(n);
return 0;
}
Output:
13
Source
https://www.geeksforgeeks.org/find-nth-term-a-matrix-exponentiation-example/
169
Chapter 24
C/C++
170
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
int linearSearch(int arr[], int n)
{
int i;
for(i = 0; i < n; i++)
{
if(arr[i] == i)
return i;
}
/* If no fixed point present then return -1 */
return -1;
}
/* Driver program to check above functions */
int main()
{
int arr[] = {-10, -1, 0, 3, 10, 11, 30, 50, 100};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Fixed Point is %d", linearSearch(arr, n));
getchar();
return 0;
}
Java
171
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
int n = arr.length;
System.out.println("Fixed Point is "
+ linearSearch(arr, n));
}
}
Python
C#
172
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
{
int []arr = {-10, -1, 0, 3, 10, 11, 30, 50, 100};
int n = arr.Length;
Console.Write("Fixed Point is "+ linearSearch(arr, n));
}
}
// This code is contributed by Sam007
PHP
<?php
// PHP program to check fixed point
// in an array using linear search
function linearSearch($arr, $n)
{
for($i = 0; $i < $n; $i++)
{
if($arr[$i] == $i)
return $i;
}
// If no fixed point present then
// return -1
return -1;
}
// Driver Code
$arr = array(-10, -1, 0, 3, 10,
11, 30, 50, 100);
$n = count($arr);
echo "Fixed Point is ".
linearSearch($arr,$n);
// This code is contributed by Sam007
?>
Output:
Fixed Point is 3
173
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
Java
174
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
Python
175
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
C#
PHP
<?php
176
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
Output:
Fixed Point is 3
177
Chapter 24. Find a Fixed Point (Value equal to index) in a given array
Source
https://www.geeksforgeeks.org/find-a-fixed-point-in-a-given-array/
178
Chapter 25
// A C++ program to find a peak element element using divide and conquer
#include <stdio.h>
// A binary search based function that returns index of a peak element
179
Chapter 25. Find a peak element
Java
// A Java program to find a peak element element using divide and conquer
import java.util.*;
import java.lang.*;
import java.io.*;
class PeakElement
{
// A binary search based function that returns index of a peak
// element
static int findPeakUtil(int arr[], int low, int high, int n)
{
180
Chapter 25. Find a peak element
Python3
181
Chapter 25. Find a peak element
mid = int(mid)
# Compare middle element with its
# neighbours (if neighbours exist)
if ((mid == 0 or arr[mid - 1] <= arr[mid]) and
(mid == n - 1 or arr[mid + 1] <= arr[mid])):
return mid
# If middle element is not peak and
# its left neighbour is greater
# than it, then left half must
# have a peak element
elif (mid > 0 and arr[mid - 1] > arr[mid]):
return findPeakUtil(arr, low, (mid - 1), n)
# If middle element is not peak and
# its right neighbour is greater
# than it, then right half must
# have a peak element
else:
return findPeakUtil(arr, (mid + 1), high, n)
# A wrapper over recursive
# function findPeakUtil()
def findPeak(arr, n):
return findPeakUtil(arr, 0, n - 1, n)
# Driver code
arr = [1, 3, 20, 4, 1, 0]
n = len(arr)
print("Index of a peak point is", findPeak(arr, n))
# This code is contributed by
# Smitha Dinesh Semwal
C#
// A C# program to find
// a peak element element
// using divide and conquer
using System;
class GFG
{
182
Chapter 25. Find a peak element
// A binary search based
// function that returns
// index of a peak element
static int findPeakUtil(int []arr, int low,
int high, int n)
{
// Find index of
// middle element
int mid = low + (high - low) / 2;
// Compare middle element with
// its neighbours (if neighbours
// exist)
if ((mid == 0 ||
arr[mid - 1] <= arr[mid]) &&
(mid == n - 1 ||
arr[mid + 1] <= arr[mid]))
return mid;
// If middle element is not
// peak and its left neighbor
// is greater than it,then
// left half must have a
// peak element
else if (mid > 0 &&
arr[mid - 1] > arr[mid])
return findPeakUtil(arr, low,
(mid - 1), n);
// If middle element is not
// peak and its right neighbor
// is greater than it, then
// right half must have a peak
// element
else return findPeakUtil(arr, (mid + 1),
high, n);
}
// A wrapper over recursive
// function findPeakUtil()
static int findPeak(int []arr,
int n)
{
return findPeakUtil(arr, 0,
n - 1, n);
}
183
Chapter 25. Find a peak element
PHP
<?php
// A PHP program to find a
// peak element element using
// divide and conquer
// A binary search based function
// that returns index of a peak
// element
function findPeakUtil($arr, $low,
$high, $n)
{
// Find index of middle element
$mid = $low + ($high - $low) / 2; // (low + high)/2
// Compare middle element with
// its neighbours (if neighbours exist)
if (($mid == 0 ||
$arr[$mid - 1] <= $arr[$mid]) &&
($mid == $n - 1 ||
$arr[$mid + 1] <= $arr[$mid]))
return $mid;
// If middle element is not peak
// and its left neighbour is greater
// than it, then left half must
// have a peak element
else if ($mid > 0 &&
$arr[$mid - 1] > $arr[$mid])
return findPeakUtil($arr, $low,
($mid - 1), $n);
// If middle element is not peak
184
Chapter 25. Find a peak element
Output :
185
Chapter 25. Find a peak element
Source
https://www.geeksforgeeks.org/find-a-peak-in-a-given-array/
186
Chapter 26
Input : 10 20 15
21 30 14
7 16 32
Output : 30
30 is a peak element because all its
neighbors are smaller or equal to it.
32 can also be picked as a peak.
Input : 10 7
11 17
Output : 17
187
Chapter 26. Find a peak element in a 2D array
188
Chapter 26. Find a peak element in a 2D array
// If we are on the first or last column,
// max is a peak
if (mid == 0 || mid == columns-1)
return max;
// If mid column maximum is also peak
if (max >= arr[max_index][mid-1] &&
max >= arr[max_index][mid+1])
return max;
// If max is less than its left
if (max < arr[max_index][mid-1])
return findPeakRec(arr, rows, columns, mid - mid/2);
// If max is less than its left
// if (max < arr[max_index][mid+1])
return findPeakRec(arr, rows, columns, mid+mid/2);
}
// A wrapper over findPeakRec()
int findPeak(int arr[][MAX], int rows, int columns)
{
return findPeakRec(arr, rows, columns, columns/2);
}
// Driver Code
int main()
{
int arr[][MAX] = {{ 10, 8, 10, 10 },
{ 14, 13, 12, 11 },
{ 15, 9, 11, 21 },
{ 16, 17, 19, 20 } };
// Number of Columns
int rows = 4, columns = 4;
cout << findPeak(arr, rows, columns);
return 0;
}
Output: 21
Time Complexity : O(rows * log(columns)). We recur for half number of columns. In every
recursive call we linearly search for maximum in current mid column.
Auxiliary Space : O(columns/2) for Recursion Call Stack
Source:
189
Chapter 26. Find a peak element in a 2D array
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-201
lecture-videos/MIT6_006F11_lec01.pdf
Source
https://www.geeksforgeeks.org/find-peak-element-2d-array/
190
Chapter 27
A simple solution for this problem is to use linear search. Element arr[i] is bitonic point
if both i-1’th and i+1’th both elements are less than i’th element. Time complexity for this
approach is O(n).
An efficient solution for this problem is to use modified binary search.
• If arr[mid-1] < arr[mid] and arr[mid] > arr[mid+1] then we are done with
bitonic point.
• If arr[mid] < arr[mid+1] then search in right sub-array, else search in left sub-array.
191
Chapter 27. Find bitonic point in given bitonic sequence
C++
Java
192
Chapter 27. Find bitonic point in given bitonic sequence
import java.io.*;
class GFG
{
// Function to find bitonic point
// using binary search
static int binarySearch(int arr[], int left,
int right)
{
if (left <= right)
{
int mid = (left + right) / 2;
// base condition to check if arr[mid]
// is bitonic point or not
if (arr[mid - 1] < arr[mid] &&
arr[mid] > arr[mid + 1])
return mid;
// We assume that sequence is bitonic. We go to
// right subarray if middle point is part of
// increasing subsequence. Else we go to left
// subarray.
if (arr[mid] < arr[mid + 1])
return binarySearch(arr, mid + 1, right);
else
return binarySearch(arr, left, mid - 1);
}
return -1;
}
// Driver program
public static void main (String[] args)
{
int arr[] = {6, 7, 8, 11, 9, 5, 2, 1};
int n = arr.length;
int index = binarySearch(arr, 1, n - 2);
if (index != -1)
System.out.println ( arr[index]);
}
}
// This code is contributed by vt_m
C#
193
Chapter 27. Find bitonic point in given bitonic sequence
PHP
194
Chapter 27. Find bitonic point in given bitonic sequence
<?php
// PHP program to find bitonic
// point in a bitonic array.
// Function to find bitonic point
// using binary search
function binarySearch($arr, $left, $right)
{
if ($left <= $right)
{
$mid = ($left + $right) / 2;
// base condition to check if
// arr[mid] is bitonic point
// or not
if ($arr[$mid - 1] < $arr[$mid] &&
$arr[$mid] > $arr[$mid + 1])
return $mid;
// We assume that sequence
// is bitonic. We go to right
// subarray if middle point
// is part of increasing
// subsequence. Else we go
// to left subarray.
if ($arr[$mid] < $arr[$mid + 1])
return binarySearch($arr, $mid + 1,$right);
else
return binarySearch($arr, $left, $mid - 1);
}
return -1;
}
// Driver Code
$arr = array(6, 7, 8, 11, 9, 5, 2, 1);
$n = sizeof($arr);
$index = binarySearch($arr, 1, $n-2);
if ($index != -1)
echo $arr[$index];
// This code is contributed by nitin mittal
?>
Output:
11
195
Chapter 27. Find bitonic point in given bitonic sequence
Source
https://www.geeksforgeeks.org/find-bitonic-point-given-bitonic-sequence/
196
Chapter 28
A simple solution is to traverse through the given array and keep track of absolute differ-
ence of current element with every element. Finally return the element that has minimum
absolution difference.
An efficient solution is to use Binary Search.
C++
197
Chapter 28. Find closest number in array
198
Chapter 28. Find closest number in array
Java
199
Chapter 28. Find closest number in array
/* If target is less than array element,
then search in left */
if (target < arr[mid]) {
// If target is greater than previous
// to mid, return closest of two
if (mid > 0 && target > arr[mid - 1])
return getClosest(arr[mid - 1],
arr[mid], target);
/* Repeat for left half */
j = mid;
}
// If target is greater than mid
else {
if (mid < n-1 && target < arr[mid + 1])
return getClosest(arr[mid],
arr[mid + 1], target);
i = mid + 1; // update i
}
}
// Only single element left after search
return arr[mid];
}
// Method to compare which one is the more close
// We find the closest by taking the difference
// between the target and both values. It assumes
// that val2 is greater than val1 and target lies
// between these two.
public static int getClosest(int val1, int val2,
int target)
{
if (target - val1 >= val2 - target)
return val2;
else
return val1;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 2, 4, 5, 6, 6, 8, 9 };
int target = 11;
System.out.println(findClosest(arr, target));
200
Chapter 28. Find closest number in array
}
}
Python 3
201
Chapter 28. Find closest number in array
# Method to compare which one is the more close.
# We find the closest by taking the difference
# between the target and both values. It assumes
# that val2 is greater than val1 and target lies
# between these two.
def getClosest(val1, val2, target):
if (target - val1 >= val2 - target):
return val2
else:
return val1
# Driver code
arr = [1, 2, 4, 5, 6, 6, 8, 9]
n = len(arr)
target = 11
print(findClosest(arr, n, target))
# This code is contributed by Smitha Dinesh Semwal
C#
202
Chapter 28. Find closest number in array
if (arr[mid] == target)
return arr[mid];
/* If target is less
than array element,
then search in left */
if (target < arr[mid])
{
// If target is greater
// than previous to mid,
// return closest of two
if (mid > 0 && target > arr[mid - 1])
return getClosest(arr[mid - 1],
arr[mid], target);
/* Repeat for left half */
j = mid;
}
// If target is
// greater than mid
else
{
if (mid < n-1 && target < arr[mid + 1])
return getClosest(arr[mid],
arr[mid + 1], target);
i = mid + 1; // update i
}
}
// Only single element
// left after search
return arr[mid];
}
// Method to compare which one
// is the more close We find the
// closest by taking the difference
// between the target and both
// values. It assumes that val2 is
// greater than val1 and target
// lies between these two.
public static int getClosest(int val1, int val2,
int target)
{
if (target - val1 >= val2 - target)
203
Chapter 28. Find closest number in array
return val2;
else
return val1;
}
// Driver code
public static void Main()
{
int []arr = {1, 2, 4, 5,
6, 6, 8, 9};
int target = 11;
Console.WriteLine(findClosest(arr, target));
}
}
// This code is contributed by anuj_67.
Output:
Source
https://www.geeksforgeeks.org/find-closest-number-array/
204
Chapter 29
Input: n = 3
Output: Cubic Root is 1.442250
Input: n = 8
Output: Cubic Root is 2.000000
We can use binary search. First we define error e. Let us say 0.0000001 in our case. The
main steps of our algorithm for calculating the cubic root of a number n are:
C++
205
Chapter 29. Find cubic root of a number
// Returns the absolute value of n-mid*mid*mid
double diff(double n,double mid)
{
if (n > (mid*mid*mid))
return (n-(mid*mid*mid));
else
return ((mid*mid*mid) - n);
}
// Returns cube root of a no n
double cubicRoot(double n)
{
// Set start and end for binary search
double start = 0, end = n;
// Set precision
double e = 0.0000001;
while (true)
{
double mid = (start + end)/2;
double error = diff(n, mid);
// If error is less than e then mid is
// our answer so return mid
if (error <= e)
return mid;
// If mid*mid*mid is greater than n set
// end = mid
if ((mid*mid*mid) > n)
end = mid;
// If mid*mid*mid is less than n set
// start = mid
else
start = mid;
}
}
// Driver code
int main()
{
double n = 3;
printf("Cubic root of %lf is %lf\n",
n, cubicRoot(n));
return 0;
206
Chapter 29. Find cubic root of a number
Java
207
Chapter 29. Find cubic root of a number
}
// Driver program to test above function
public static void main (String[] args)
{
double n = 3;
System.out.println("Cube root of "+n+" is "+cubicRoot(n));
}
}
// This code is contributed by Pramod Kumar
Python3
208
Chapter 29. Find cubic root of a number
C#
209
Chapter 29. Find cubic root of a number
PHP
<?php
// PHP program to find cubic root
// of a number using Binary Search
// Returns the absolute value
// of n - mid * mid * mid
function diff($n,$mid)
{
if ($n > ($mid * $mid * $mid))
return ($n - ($mid *
$mid * $mid));
else
return (($mid * $mid *
$mid) - $n);
}
210
Chapter 29. Find cubic root of a number
Output:
211
Chapter 29. Find cubic root of a number
Source
https://www.geeksforgeeks.org/find-cubic-root-of-a-number/
212
Chapter 30
Find frequency of each element in a limited range array in less than O(n) time - Geeks-
forGeeks
Given an sorted array of positive integers, count number of occurrences for each element in
the array. Assume all elements in the array are less than some constant M.
Do this without traversing the complete array. i.e. expected time complexity is less than
O(n).
Examples:
213
Chapter 30. Find frequency of each element in a limited range array in less than O(n) time
to recursively divide the array into two equal subarrays if its end elements are different. If
both its end elements are same, that means that all elements in the subarray is also same
as the array is already sorted. We then simply increment the count of the element by size
of the subarray.
The time complexity of above approach is O(m log n), where m is number of distinct elements
in the array of size n. Since m <= M (a constant), the time complexity of this solution is
O(log n).
Below is C++ implementation of above idea –
214
Chapter 30. Find frequency of each element in a limited range array in less than O(n) time
Output:
Source
https://www.geeksforgeeks.org/find-frequency-of-each-element-in-a-limited-range-array-in-less-than-on-time/
215
Chapter 31
Method 1 (Basic)
The basic method is to iterate through the whole second array and check element by
element if they are different.
C++
216
Chapter 31. Find index of an extra element present in one sorted array
Java
217
Chapter 31. Find index of an extra element present in one sorted array
Python3
C#
218
Chapter 31. Find index of an extra element present in one sorted array
PHP
<?php
// PHP program to find an extra
// element present in arr1[]
// Returns index of extra element
// in arr1[]. n is size of arr2[].
// Size of arr1[] is n-1.
function findExtra($arr1,
$arr2, $n)
{
219
Chapter 31. Find index of an extra element present in one sorted array
Output :
C++
220
Chapter 31. Find index of an extra element present in one sorted array
Java
221
Chapter 31. Find index of an extra element present in one sorted array
222
Chapter 31. Find index of an extra element present in one sorted array
Python3
223
Chapter 31. Find index of an extra element present in one sorted array
return index
# Driver code
arr1 = [2, 4, 6, 8, 10, 12, 13]
arr2 = [2, 4, 6, 8, 10, 12]
n = len(arr2)
# Solve is passed both arrays
print(findExtra(arr1, arr2, n))
# This code is contributed by Nikita Tiwari.
C#
224
Chapter 31. Find index of an extra element present in one sorted array
left = mid + 1;
// If middle element is
// different of the arrays,
// it means that the index
// we are searching for is
// either mid, or before mid.
// Hence we update right to mid-1.
else
{
index = mid;
right = mid - 1;
}
}
// when right is greater
// than left our
// search is complete.
return index;
}
// Driver Code
public static void Main ()
{
int []arr1 = {2, 4, 6, 8, 10, 12,13};
int []arr2 = {2, 4, 6, 8, 10, 12};
int n = arr2.Length;
// Solve is passed
// both arrays
Console.Write(findExtra(arr1, arr2, n));
}
}
// This code is contributed by nitin mittal.
PHP
<?php
// PHP program to find an extra
// element present in arr1[]
// Returns index of extra element
// in arr1[]. n is size of arr2[].
// Size of arr1[] is n-1.
function findExtra($arr1, $arr2, $n)
{
// Initialize result
225
Chapter 31. Find index of an extra element present in one sorted array
$index = $n;
// left and right are
// end points denoting
// the current range.
$left = 0; $right = $n - 1;
while ($left <= $right)
{
$mid = ($left+$right) / 2;
// If middle element is same
// of both arrays, it means
// that extra element is after
// mid so we update left to mid+1
if ($arr2[$mid] == $arr1[$mid])
$left = $mid + 1;
// If middle element is different
// of the arrays, it means that the
// index we are searching for is either
// mid, or before mid. Hence we update
// right to mid-1.
else
{
$index = $mid;
$right = $mid - 1;
}
}
// when right is greater than
// left, our search is complete.
return $index;
}
// Driver code
{
$arr1 = array(2, 4, 6, 8,
10, 12, 13);
$arr2 = array(2, 4, 6,
8, 10, 12);
$n = sizeof($arr2) / sizeof($arr2[0]);
// Solve is passed both arrays
echo findExtra($arr1, $arr2, $n);
return 0;
}
// This code is contributed by nitin mittal
226
Chapter 31. Find index of an extra element present in one sorted array
?>
Output :
Source
https://www.geeksforgeeks.org/find-index-of-an-extra-element-present-in-one-sorted-array/
227
Chapter 32
One Simple solution is to apply methods discussed for finding the missing element in an
unsorted array. Time complexity of this solution is O(n).
An efficient solution is based on the divide and conquer algorithm that we have seen in
binary search, the concept behind this solution is that the elements appearing before the
missing element will have ar[i] – i = 1 and those appearing after the missing element will
have ar[i] – i = 2.
This solution has a time complexity of O(log n)
C++
228
Chapter 32. Find the Missing Number in a sorted array
#include <iostream>
using namespace std;
int search(int ar[], int size)
{
int a = 0, b = size - 1;
int mid;
while ((b - a) > 1) {
mid = (a + b) / 2;
if ((ar[a] - a) != (ar[mid] - mid))
b = mid;
else if ((ar[b] - b) != (ar[mid] - mid))
a = mid;
}
return (ar[mid] + 1);
}
int main()
{
int ar[] = { 1, 2, 3, 4, 5, 6, 8 };
int size = sizeof(ar) / sizeof(ar[0]);
cout << "Missing number:" << search(ar, size);
}
Java
229
Chapter 32. Find the Missing Number in a sorted array
}
// Driver Code
public static void main (String[] args)
{
int ar[] = { 1, 2, 3, 4, 5, 6, 8 };
int size = ar.length;
System.out.println("Missing number: " +
search(ar, size));
}
}
// This code is contributed
// by inder_verma.
C#
230
Chapter 32. Find the Missing Number in a sorted array
}
}
// This code is contributed
// by Arnab Kundu
Output:
Missing number: 7
Source
https://www.geeksforgeeks.org/find-the-missing-number-in-a-sorted-array/
231
Chapter 33
C++
232
Chapter 33. Find the Rotation Count in Rotated Sorted array
#include<bits/stdc++.h>
using namespace std;
// Returns count of rotations for an array which
// is first sorted in ascending order, then rotated
int countRotations(int arr[], int n)
{
// We basically find index of minimum
// element
int min = arr[0], min_index;
for (int i=0; i<n; i++)
{
if (min > arr[i])
{
min = arr[i];
min_index = i;
}
}
return min_index;
}
// Driver code
int main()
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = sizeof(arr)/sizeof(arr[0]);
cout << countRotations(arr, n);
return 0;
}
Java
233
Chapter 33. Find the Rotation Count in Rotated Sorted array
Python3
234
Chapter 33. Find the Rotation Count in Rotated Sorted array
C#
PHP
<?php
235
Chapter 33. Find the Rotation Count in Rotated Sorted array
Output:
• The minimum element is the only element whose previous is greater than it. If there
is no previous element element, then there is no rotation (first element is minimum).
236
Chapter 33. Find the Rotation Count in Rotated Sorted array
We check this condition for middle element by comparing it with (mid-1)’th and
(mid+1)’th elements.
• If minimum element is not at middle (neither mid nor mid + 1), then minimum element
lies in either left half or right half.
1. If middle element is smaller than last element, then the minimum element lies in
left half
2. Else minimum element lies in right half.
C++
237
Chapter 33. Find the Rotation Count in Rotated Sorted array
Java
238
Chapter 33. Find the Rotation Count in Rotated Sorted array
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left
// half or right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid - 1);
return countRotations(arr, mid + 1, high);
}
// Driver program to test above functions
public static void main (String[] args)
{
int arr[] = {15, 18, 2, 3, 6, 12};
int n = arr.length;
System.out.println(countRotations(arr, 0, n-1));
}
}
// This code is contributed by Chhavi
Python3
239
Chapter 33. Find the Rotation Count in Rotated Sorted array
C#
240
Chapter 33. Find the Rotation Count in Rotated Sorted array
// If there is only one element left
if (high == low)
return low;
// Find mid
// /*(low + high)/2;*/
int mid = low + (high - low)/2;
// Check if element (mid+1) is minimum
// element. Consider the cases like
// {3, 4, 5, 1, 2}
if (mid < high && arr[mid+1] < arr[mid])
return (mid + 1);
// Check if mid itself is minimum element
if (mid > low && arr[mid] < arr[mid - 1])
return mid;
// Decide whether we need to go to left
// half or right half
if (arr[high] > arr[mid])
return countRotations(arr, low, mid - 1);
return countRotations(arr, mid + 1, high);
}
// Driver program to test above functions
public static void Main ()
{
int []arr = {15, 18, 2, 3, 6, 12};
int n = arr.Length;
Console.WriteLine(countRotations(arr, 0, n-1));
}
}
// This code is contributed by vt_m.
PHP
<?php
// Binary Search based PHP
// program to find number
// of rotations in a sorted
// and rotated array.
// Returns count of rotations
// for an array which is
241
Chapter 33. Find the Rotation Count in Rotated Sorted array
242
Chapter 33. Find the Rotation Count in Rotated Sorted array
Output:
Source
https://www.geeksforgeeks.org/find-rotation-count-rotated-sorted-array/
243
Chapter 34
A Simple Solution is to traverse the array from left to right. Since the array is sorted, we
can easily figure out the required element.
An Efficient Solution can find the required element in O(Log n) time. The idea is to use
Binary Search. Below is an observation in input array.
All elements before the required have first occurrence at even index (0, 2, ..) and next
occurrence at odd index (1, 3, …). And all elements after the required element have first
occurrence at odd index and next occurrence at even index.
1) Find the middle index, say ‘mid’.
2) If ‘mid’ is even, then compare arr[mid] and arr[mid + 1]. If both are same, then the
required element after ‘mid’ else before mid.
3) If ‘mid’ is odd, then compare arr[mid] and arr[mid – 1]. If both are same, then the
required element after ‘mid’ else before mid.
Below is the implementation based on above idea.
244
Chapter 34. Find the element that appears once in a sorted array
C/C++
245
Chapter 34. Find the element that appears once in a sorted array
Java
246
Chapter 34. Find the element that appears once in a sorted array
}
// This code is contributed by Tanisha Mittal
Python
247
Chapter 34. Find the element that appears once in a sorted array
C#
248
Chapter 34. Find the element that appears once in a sorted array
}
// Driver Code
public static void Main(String[] args)
{
int[] arr = {1, 1, 2, 4, 4, 5, 5, 6, 6};
search(arr, 0, arr.Length - 1);
}
}
// This code is contributed by Nitin Mittal.
PHP
<?php
// PHP program to find the element
// that appears only once
// A Binary Search based function
// to find the element that
// appears only once
function search($arr, $low, $high)
{
// Base cases
if ($low > $high)
return;
if ($low==$high)
{
echo("The required element is " );
echo $arr[$low] ;
return;
}
// Find the middle point
$mid = ($low + $high) / 2;
// If mid is even and element
// next to mid is same as mid,
// then output element lies on
// right side, else on left side
if ($mid % 2 == 0)
{
if ($arr[$mid] == $arr[$mid + 1])
search($arr, $mid + 2, $high);
else
search($arr, $low, $mid);
249
Chapter 34. Find the element that appears once in a sorted array
}
// If mid is odd
else
{
if ($arr[$mid] == $arr[$mid - 1])
search($arr, $mid + 1, $high);
else
search($arr, $low, $mid - 1);
}
}
// Driver Code
$arr = array(1, 1, 2, 4, 4, 5, 5, 6, 6);
$len = sizeof($arr);
search($arr, 0, $len - 1);
// This code is contributed by nitin mittal
?>
Output:
Source
https://www.geeksforgeeks.org/find-the-element-that-appears-once-in-a-sorted-array/
250
Chapter 35
Find the maximum element in an array which is first increasing and then decreasing -
GeeksforGeeks
Given an array of integers which is initially increasing and then decreasing, find the maxi-
mum value in the array.
Examples :
Input: arr[] = {8, 10, 20, 80, 100, 200, 400, 500, 3, 2, 1}
Output: 500
251
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
#include <stdio.h>
int findMaximum(int arr[], int low, int high)
{
int max = arr[low];
int i;
for (i = low; i <= high; i++)
{
if (arr[i] > max)
max = arr[i];
}
return max;
}
/* Driver program to check above functions */
int main()
{
int arr[] = {1, 30, 40, 50, 60, 70, 23, 20};
int n = sizeof(arr)/sizeof(arr[0]);
printf("The maximum element is %d", findMaximum(arr, 0, n-1));
getchar();
return 0;
}
Java
252
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
int arr[] = {1, 30, 40, 50, 60, 70, 23, 20};
int n = arr.length;
System.out.println("The maximum element is "+
findMaximum(arr, 0, n-1));
}
}
Python3
C#
253
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
return max;
}
// Driver code
public static void Main ()
{
int []arr = {1, 30, 40, 50, 60, 70, 23, 20};
int n = arr.Length;
Console.Write("The maximum element is "+
findMaximum(arr, 0, n-1));
}
}
// This code is contributed by Sam007
PHP
<?php
// PHP program to Find the maximum
// element in an array which is first
// increasing and then decreasing
function findMaximum($arr, $low, $high)
{
$max = $arr[$low];
$i;
for ($i = $low; $i <= $high; $i++)
{
if ($arr[$i] > $max)
$max = $arr[$i];
}
return $max;
}
// Driver Code
$arr = array(1, 30, 40, 50,
60, 70, 23, 20);
$n = count($arr);
echo "The maximum element is ",
findMaximum($arr, 0, $n-1);
// This code is contributed by anuj_67.
?>
Output :
254
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
#include <stdio.h>
int findMaximum(int arr[], int low, int high)
{
/* Base Case: Only one element is present in arr[low..high]*/
if (low == high)
return arr[low];
/* If there are two elements and first is greater then
the first element is maximum */
if ((high == low + 1) && arr[low] >= arr[high])
return arr[low];
/* If there are two elements and second is greater then
the second element is maximum */
if ((high == low + 1) && arr[low] < arr[high])
return arr[high];
int mid = (low + high)/2; /*low + (high - low)/2;*/
/* If we reach a point where arr[mid] is greater than both of
its adjacent elements arr[mid-1] and arr[mid+1], then arr[mid]
is the maximum element*/
if ( arr[mid] > arr[mid + 1] && arr[mid] > arr[mid - 1])
return arr[mid];
/* If arr[mid] is greater than the next element and smaller than the previous
element then maximum lies on left side of mid */
if (arr[mid] > arr[mid + 1] && arr[mid] < arr[mid - 1])
return findMaximum(arr, low, mid-1);
else // when arr[mid] is greater than arr[mid-1] and smaller than arr[mid+1]
return findMaximum(arr, mid + 1, high);
}
/* Driver program to check above functions */
int main()
255
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
{
int arr[] = {1, 3, 50, 10, 9, 7, 6};
int n = sizeof(arr)/sizeof(arr[0]);
printf("The maximum element is %d", findMaximum(arr, 0, n-1));
getchar();
return 0;
}
Java
256
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
Python3
257
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
else: # when arr[mid] is greater than arr[mid-1] and smaller than arr[mid+1]
return findMaximum(arr, mid + 1, high)
# Driver program to check above functions */
arr = [1, 3, 50, 10, 9, 7, 6]
n = len(arr)
print ("The maximum element is %d"% findMaximum(arr, 0, n-1))
# This code is contributed by Shreyanshi Arun.
C#
258
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
return arr[mid];
/* If arr[mid] is greater than the next
element and smaller than the previous
element then maximum lies on left side
of mid */
if (arr[mid] > arr[mid + 1] && arr[mid] < arr[mid - 1])
return findMaximum(arr, low, mid-1);
else
return findMaximum(arr, mid + 1, high);
}
// main function
public static void Main()
{
int []arr = {1, 3, 50, 10, 9, 7, 6};
int n = arr.Length;
Console.Write("The maximum element is "+
findMaximum(arr, 0, n-1));
}
}
// This code is contributed by Sam007
PHP
<?php
// PHP program to Find the maximum
// element in an array which is
// first increasing and then decreasing
function findMaximum($arr, $low, $high)
{
/* Base Case: Only one element
is present in arr[low..high]*/
if ($low == $high)
return $arr[$low];
/* If there are two elements
and first is greater then
the first element is maximum */
if (($high == $low + 1) &&
$arr[$low] >= $arr[$high])
return $arr[$low];
/* If there are two elements
and second is greater then
the second element is maximum */
259
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
Output :
260
Chapter 35. Find the maximum element in an array which is first increasing and then
decreasing
Source
https://www.geeksforgeeks.org/find-the-maximum-element-in-an-array-which-is-first-increasing-and-then-decreasin
261
Chapter 36
Input: {5, 6, 1, 2, 3, 4}
Output: 1
Input: {1, 2, 3, 4}
Output: 1
Input: {2, 1}
Output: 1
A simple solution is to traverse the complete array and find minimum. This solution requires
?(n) time.
We can do it in O(Logn) using Binary Search. If we take a closer look at above examples,
we can easily figure out following pattern:
• The minimum element is the only element whose previous is greater than it. If there
is no previous element element, then there is no rotation (first element is minimum).
We check this condition for middle element by comparing it with (mid-1)’th and
(mid+1)’th elements.
• If minimum element is not at middle (neither mid nor mid + 1), then minimum element
lies in either left half or right half.
262
Chapter 36. Find the minimum element in a sorted and rotated array
1. If middle element is smaller than last element, then the minimum element lies in
left half
2. Else minimum element lies in right half.
We strongly recommend you to try it yourself before seeing the following implementation.
C/C++
263
Chapter 36. Find the minimum element in a sorted and rotated array
int arr3[] = {1};
int n3 = sizeof(arr3)/sizeof(arr3[0]);
printf("The minimum element is %d\n", findMin(arr3, 0, n3-1));
int arr4[] = {1, 2};
int n4 = sizeof(arr4)/sizeof(arr4[0]);
printf("The minimum element is %d\n", findMin(arr4, 0, n4-1));
int arr5[] = {2, 1};
int n5 = sizeof(arr5)/sizeof(arr5[0]);
printf("The minimum element is %d\n", findMin(arr5, 0, n5-1));
int arr6[] = {5, 6, 7, 1, 2, 3, 4};
int n6 = sizeof(arr6)/sizeof(arr6[0]);
printf("The minimum element is %d\n", findMin(arr6, 0, n6-1));
int arr7[] = {1, 2, 3, 4, 5, 6, 7};
int n7 = sizeof(arr7)/sizeof(arr7[0]);
printf("The minimum element is %d\n", findMin(arr7, 0, n7-1));
int arr8[] = {2, 3, 4, 5, 6, 7, 8, 1};
int n8 = sizeof(arr8)/sizeof(arr8[0]);
printf("The minimum element is %d\n", findMin(arr8, 0, n8-1));
int arr9[] = {3, 4, 5, 1, 2};
int n9 = sizeof(arr9)/sizeof(arr9[0]);
printf("The minimum element is %d\n", findMin(arr9, 0, n9-1));
return 0;
}
Java
264
Chapter 36. Find the minimum element in a sorted and rotated array
265
Chapter 36. Find the minimum element in a sorted and rotated array
int n7 = arr7.length;
System.out.println("The minimum element is "+ findMin(arr7, 0, n7-1));
int arr8[] = {2, 3, 4, 5, 6, 7, 8, 1};
int n8 = arr8.length;
System.out.println("The minimum element is "+ findMin(arr8, 0, n8-1));
int arr9[] = {3, 4, 5, 1, 2};
int n9 = arr9.length;
System.out.println("The minimum element is "+ findMin(arr9, 0, n9-1));
}
}
Python
266
Chapter 36. Find the minimum element in a sorted and rotated array
C#
267
Chapter 36. Find the minimum element in a sorted and rotated array
268
Chapter 36. Find the minimum element in a sorted and rotated array
PHP
<?php
// PHP program to find minimum
// element in a sorted and
// rotated array
function findMin($arr, $low,
$high)
{
// This condition is needed
// to handle the case when
// array is not rotated at all
if ($high < $low) return $arr[0];
// If there is only
269
Chapter 36. Find the minimum element in a sorted and rotated array
270
Chapter 36. Find the minimum element in a sorted and rotated array
Output:
271
Chapter 36. Find the minimum element in a sorted and rotated array
or right half by doing constant number of comparisons at the middle. So the problem with
repetition can be solved in O(n) worst case.
This article is contributed by Abhay Rathi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : ChitraNayal
Source
https://www.geeksforgeeks.org/find-minimum-element-in-a-sorted-and-rotated-array/
272
Chapter 37
A Simple Solution is to linearly traverse the array and find the missing number. Time
complexity of this solution is O(n).
We can solve this problem in O(Logn) time using Binary Search. The idea is to go to the
middle element. Check if the difference between middle and next to middle is equal to diff
or not, if not then the missing element lies between mid and mid+1. If the middle element
is equal to n/2th term in Arithmetic Series (Let n be the number of elements in input array),
then missing element lies in right half. Else element lies in left half.
Following is implementation of above idea.
273
Chapter 37. Find the missing number in Arithmetic Progression
#include <limits.h>
// A binary search based recursive function that returns
// the missing element in arithmetic progression
int findMissingUtil(int arr[], int low, int high, int diff)
{
// There must be two elements to find the missing
if (high <= low)
return INT_MAX;
// Find index of middle element
int mid = low + (high - low)/2;
// The element just after the middle element is missing.
// The arr[mid+1] must exist, because we return when
// (low == high) and take floor of (high-low)/2
if (arr[mid+1] - arr[mid] != diff)
return (arr[mid] + diff);
// The element just before mid is missing
if (mid > 0 && arr[mid] - arr[mid-1] != diff)
return (arr[mid-1] + diff);
// If the elements till mid follow AP, then recur
// for right half
if (arr[mid] == arr[0] + mid*diff)
return findMissingUtil(arr, mid+1, high, diff);
// Else recur for left half
return findMissingUtil(arr, low, mid-1, diff);
}
// The function uses findMissingUtil() to find the missing
// element in AP. It assumes that there is exactly one missing
// element and may give incorrect result when there is no missing
// element or more than one missing elements.
// This function also assumes that the difference in AP is an
// integer.
int findMissing(int arr[], int n)
{
// If exactly one element is missing, then we can find
// difference of arithmetic progression using following
// formula. Example, 2, 4, 6, 10, diff = (10-2)/4 = 2.
// The assumption in formula is that the difference is
// an integer.
int diff = (arr[n-1] - arr[0])/n;
// Binary search for the missing number using above
274
Chapter 37. Find the missing number in Arithmetic Progression
Java
275
Chapter 37. Find the missing number in Arithmetic Progression
276
Chapter 37. Find the missing number in Arithmetic Progression
C#
// A C# program to find
// the missing number in
// a given arithmetic
// progression
using System;
class GFG
{
// A binary search based
// recursive function that
// returns the missing
// element in arithmetic
// progression
static int findMissingUtil(int []arr, int low,
int high, int diff)
{
// There must be two elements
// to find the missing
if (high <= low)
return int.MaxValue;
// Find index of
// middle element
int mid = low + (high -
low) / 2;
// The element just after the
// middle element is missing.
// The arr[mid+1] must exist,
// because we return when
// (low == high) and take
// floor of (high-low)/2
if (arr[mid + 1] -
arr[mid] != diff)
return (arr[mid] + diff);
// The element just
// before mid is missing
277
Chapter 37. Find the missing number in Arithmetic Progression
278
Chapter 37. Find the missing number in Arithmetic Progression
Output:
Exercise:
Solve the same problem for Geometrical Series. What is the time complexity of your solu-
tion? What about Fibonacci Series?
This article is contributed by Harshit Agrawal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : vt_m
Source
https://www.geeksforgeeks.org/find-missing-number-arithmetic-progression/
279
Chapter 38
280
Chapter 38. Find the number of zeroes
Java
281
Chapter 38. Find the number of zeroes
Python3
282
Chapter 38. Find the number of zeroes
C#
283
Chapter 38. Find the number of zeroes
284
Chapter 38. Find the number of zeroes
}
}
// This code is contributed by nitin mittal.
PHP
<?php
// A divide and conquer solution to
// find count of zeroes in an array
// where all 1s are present before all 0s
/* if 0 is present in arr[] then
returns the index of FIRST
occurrence of 0 in arr[low..high],
otherwise returns -1 */
function firstZero($arr, $low, $high)
{
if ($high >= $low)
{
// Check if mid element is first 0
$mid = $low + floor(($high - $low)/2);
if (( $mid == 0 || $arr[$mid-1] == 1) &&
$arr[$mid] == 0)
return $mid;
// If mid element is not 0
if ($arr[$mid] == 1)
return firstZero($arr, ($mid + 1), $high);
// If mid element is 0,
// but not first 0
else
return firstZero($arr, $low,
($mid - 1));
}
return -1;
}
// A wrapper over recursive
// function firstZero()
function countZeroes($arr, $n)
{
// Find index of first
// zero in given array
285
Chapter 38. Find the number of zeroes
Output:
Count of zeroes is 5
Source
https://www.geeksforgeeks.org/find-number-zeroes/
286
Chapter 39
Input : arr[] = { 1, 2 , 3 , 4 , 4}
Output : 4
Input : arr[] = { 1 , 1 , 2 , 3 , 4}
Output : 1
A naive approach is to scan the whole array and check if an element occurs twice, then
return. This approach takes O(n) time.
An efficient method is to use Binary Search .
1- Check if the middle element is the repeating one.
2- If not then check if the middle element is at proper position if yes then start searching
repeating element in right.
3- Otherwise the repeating one will be in left.
C/C++
287
Chapter 39. Find the only repeating element in a sorted array of size n
Java
288
Chapter 39. Find the only repeating element in a sorted array of size n
{
// low = 0 , high = n-1;
if (low > high)
return -1;
int mid = (low + high) / 2;
// Check if the mid element is the repeating one
if (arr[mid] != mid + 1)
{
if (mid > 0 && arr[mid]==arr[mid-1])
return mid;
// If mid element is not at its position that means
// the repeated element is in left
return findRepeatingElement(arr, low, mid-1);
}
// If mid is at proper position then repeated one is in
// right.
return findRepeatingElement(arr, mid+1, high);
}
// Driver method
public static void main(String[] args)
{
int arr[] = {1, 2, 3, 3, 4, 5};
int index = findRepeatingElement(arr, 0, arr.length-1);
if (index != -1)
System.out.println(arr[index]);
}
}
Python
289
Chapter 39. Find the only repeating element in a sorted array of size n
# Check if the mid element is the repeating one
if (arr[mid] != mid + 1):
if (mid > 0 and arr[mid]==arr[mid-1]):
return mid
# If mid element is not at its position that means
# the repeated element is in left
return findRepeatingElement(arr, low, mid-1)
# If mid is at proper position then repeated one is in
# right.
return findRepeatingElement(arr, mid+1, high)
# Driver code
arr = [1, 2, 3, 3, 4, 5]
n = len(arr)
index = findRepeatingElement(arr, 0, n-1)
if (index is not -1):
print arr[index]
#This code is contributed by Afzal Ansari
C#
290
Chapter 39. Find the only repeating element in a sorted array of size n
{
if (mid > 0 && arr[mid]==arr[mid-1])
return mid;
// If mid element is not at its position
// that means the repeated element is in left
return findRepeatingElement(arr, low, mid-1);
}
// If mid is at proper position
// then repeated one is in right.
return findRepeatingElement(arr, mid+1, high);
}
// Driver method
public static void Main()
{
int []arr = {1, 2, 3, 3, 4, 5};
int index = findRepeatingElement(arr, 0, arr.Length-1);
if (index != -1)
Console.Write(arr[index]);
}
}
// This code is contributed by Nitin Mittal.
PHP
<?php
// PHP program to find the only
// repeating element in an array
// of size n and elements from
// range 1 to n-1.
// Returns index of second
// appearance of a repeating
// element. The function assumes
// that array elements are in
// range from 1 to n-1.
function findRepeatingElement($arr,
$low,
$high)
{
// low = 0 , high = n-1;
if ($low > $high)
return -1;
$mid = floor(($low + $high) / 2);
291
Chapter 39. Find the only repeating element in a sorted array of size n
// Check if the mid element
// is the repeating one
if ($arr[$mid] != $mid + 1)
{
if ($mid > 0 && $arr[$mid] ==
$arr[$mid - 1])
return $mid;
// If mid element is not at
// its position that means
// the repeated element is in left
return findRepeatingElement($arr, $low,
$mid - 1);
}
// If mid is at proper position
// then repeated one is in right.
return findRepeatingElement($arr, $mid + 1,
$high);
}
// Driver code
$arr = array(1, 2, 3, 3, 4, 5);
$n = sizeof($arr);
$index = findRepeatingElement($arr, 0,
$n - 1);
if ($index != -1)
echo $arr[$index];
// This code is contributed
// by nitin mittal.
?>
Output :
Source
https://www.geeksforgeeks.org/find-repeating-element-sorted-array-size-n/
292
Chapter 40
A simple solution is to linearly traverse given array and find first element that is strictly
greater. If no such element exists, then return -1.
An efficient solution is to use Binary Search. In a general binary search, we are looking for
a value which appears in the array. Sometimes, however, we need to find the first element
which is either greater than a target.
To see that this algorithm is correct, consider each comparison being made. If we find an
element that’s no greater than the target element, then it and everything below it can’t
possibly match, so there’s no need to search that region. We can thus search the right half.
If we find an element that is larger than the element in question, then anything after it must
293
Chapter 40. First strictly greater element in a sorted array in Java
also be larger, so they can’t be the first element that’s bigger and so we don’t need to search
them. The middle element is thus the last possible place it could be.
Note that on each iteration we drop off at least half the remaining elements from considera-
tion. If the top branch executes, then the elements in the range [low, (low + high) / 2] are
all discarded, causing us to lose floor((low + high) / 2) – low + 1 >= (low + high) / 2 –
low = (high – low) / 2 elements.
If the bottom branch executes, then the elements in the range [(low + high) / 2 + 1, high]
are all discarded. This loses us high – floor(low + high) / 2 + 1 >= high – (low + high) /
2 = (high – low) / 2 elements.
Consequently, we’ll end up finding the first element greater than the target in O(lg n)
iterations of this process.
294
Chapter 40. First strictly greater element in a sorted array in Java
Output:
Source
https://www.geeksforgeeks.org/first-strictly-greater-element-in-a-sorted-array-in-java/
295
Chapter 41
A simple solution is to linearly traverse given array and find first element that is strictly
greater. If no such element exists, then return -1.
An efficient solution is to useBinary Search. In a general binary search, we are looking for
a value which appears in the array. Sometimes, however, we need to find the first element
which is either greater than a target.
To see that this algorithm is correct, consider each comparison being made. If we find an
element that’s greater than the target element, then it and everything above it can’t possibly
match, so there’s no need to search that region. We can thus search the left half. If we find
an element that is smaller than the element in question, then anything before it must also
296
Chapter 41. First strictly smaller element in a sorted array in Java
be larger, so they can’t be the first element that’s smaller and so we don’t need to search
them. The middle element is thus the last possible place it could be.
Note that on each iteration we drop off at least half the remaining elements from considera-
tion. If the top branch executes, then the elements in the range [low, (low + high) / 2] are
all discarded, causing us to lose floor((low + high) / 2) – low + 1 >= (low + high) / 2 –
low = (high – low) / 2 elements.
If the bottom branch executes, then the elements in the range [(low + high) / 2 + 1, high]
are all discarded. This loses us high – floor(low + high) / 2 + 1 >= high – (low + high) /
2 = (high – low) / 2 elements.
Consequently, we’ll end up finding the first element smaller than the target in O(lg n)
iterations of this process.
297
Chapter 41. First strictly smaller element in a sorted array in Java
Output:
Source
https://www.geeksforgeeks.org/first-strictly-smaller-element-in-a-sorted-array-in-java/
298
Chapter 42
Method 1 (Simple)
A simple solution is linearly traverse input sorted array and search for the first element
greater than x. The element just before the found element is floor of x.
C++
299
Chapter 42. Floor in a Sorted Array
Python3
300
Chapter 42. Floor in a Sorted Array
return high
# Find the middle point
mid = int((low + high) / 2)
# If middle point is floor.
if (arr[mid] == x):
return mid
# If x lies between mid-1 and mid
if (mid > 0 and arr[mid-1] <= x
and x < arr[mid]):
return mid - 1
# If x is smaller than mid,
# floor must be in left half.
if (x < arr[mid]):
return floorSearch(arr, low, mid-1, x)
# If mid-1 is not floor and x is greater than
# arr[mid],
return floorSearch(arr, mid+1, high, x)
# Driver Code
arr = [1, 2, 4, 6, 10, 12, 14]
n = len(arr)
x = 7
index = floorSearch(arr, 0, n-1, x)
if (index == -1):
print("Floor of", x, "doesn't exist \
in array ", end = "")
else:
print("Floor of", x, "is", arr[index])
# This code is contributed by Smitha Dinesh Semwal.
Output:
Floor of 7 is 6.
Method 2 (Efficient)
301
Chapter 42. Floor in a Sorted Array
C++
302
Chapter 42. Floor in a Sorted Array
Java
303
Chapter 42. Floor in a Sorted Array
Python3
304
Chapter 42. Floor in a Sorted Array
C#
305
Chapter 42. Floor in a Sorted Array
// Find the middle point
int mid = (low + high) / 2;
// If middle point is floor.
if (arr[mid] == x)
return mid;
// If x lies between mid-1 and mid
if (mid > 0 && arr[mid-1] <= x && x <
arr[mid])
return mid - 1;
// If x is smaller than mid, floor
// must be in left half.
if (x < arr[mid])
return floorSearch(arr, low,
mid - 1, x);
// If mid-1 is not floor and x is
// greater than arr[mid],
return floorSearch(arr, mid + 1, high,
x);
}
/* Driver program to check above functions */
public static void Main()
{
int []arr = {1, 2, 4, 6, 10, 12, 14};
int n = arr.Length;
int x = 7;
int index = floorSearch(arr, 0, n - 1,
x);
if (index == -1)
Console.Write("Floor of " + x +
" dosen't exist in array ");
else
Console.Write("Floor of " + x +
" is " + arr[index]);
}
}
// This code is contributed by nitin mittal.
Output:
Floor of 7 is 6.
306
Chapter 42. Floor in a Sorted Array
Source
https://www.geeksforgeeks.org/floor-in-a-sorted-array/
307
Chapter 43
Input :
A[] = {9, -10, 7, 6}
B[] = {-5, 4, 0, -2}
Output :
C(x) =
In real life applications such as signal processing, speed matters a lot, this article examines an
efficient FFT implementation. This article focuses on iterative version of the FFT algorithm
that runs in O(nlogn) time but can have a lower constant hidden than the recursive version
plus it saves the recursion stack space.
Pre-requisite: recursive algorithm of FFT.
Recall the recursive-FFT pseudo code from previous post, in the for loop evaluation of ,
is calculated twice. We can change the loop to compute it only once, storing it in a
temporary variable t. So, it becomes,
for k 0 to n/2 – 1
do t
308
Chapter 43. Iterative Fast Fourier Transformation for polynomial multiplication
the product into t, and adding and subtracting t from , is known as a butterfly
operation.
Pictorially, this is what butterfly operation looks like:
Let us take for n=8 and procede for formation of iterative fft algorithm. Looking at the
recursion tree above, we find that if we arrange the elements of the initial coefficient vector
a into the order in which they appear in the leaves, we could trace the execution of the
Recusive-FFT procedure, but bottom up instead of top down. First, we take the elements in
pairs, compute the DFT of each pair using one butterfly operation, and replace the pair with
its DFT. The vector then holds n/2 2-element DFTs. Next, we take these n/2 DFTs in pairs
and compute the DFT of the four vector elements they come from by executing two butterfy
operations, replacing two 2-element DFTs with one 4-element DFT. The vector then holds
n/4 4-element DFTs. We continue in this manner until the vector holds two (n/2) el-
ement DFTs, which we combine using n/2 butterfly operations into the final n-element DFT.
309
Chapter 43. Iterative Fast Fourier Transformation for polynomial multiplication
To turn this bottom-up approach into code, we use an array A[0…n] that initially holds
the elements of the input vector a in the order in which they appear in the leaves of the
tree. Because we have to combine DFT so n each level of the tree, we introduce avariable
s to count the levels, ranging from 1 (at the bottom, when we are combining pairs to
form 2-element DFTs) to lgn (at the top, when weare combining two n/2 element DFTs to
produce the final result). The algorithm therefore is:
Now for generating the code, we arrange the coefficient vector elements in the order of leaves.
Example- The order in leaves 0, 4, 2, 6, 1, 5, 3, 7 is a bit reversal of the indices. Start with
000, 001, 010, 011, 100, 101, 110, 111 and reverse the bits of each binary number to obtain
000, 100, 010, 110, 001, 101, 011, 111.Pseudo code for iterative FFT :
BIT-REVERSE-COPY(a, A)
n = length [a]
for k = 0 to n-1
do A[rev(k)] = a[k]
ITERATIVE-FFT
BIT-REVERSE-COPY(a, A)
n = length(a)
for s = 1 to log n
do m=
=
for j = 0 to m/2-1
do for k = j to n-1 by m
310
Chapter 43. Iterative Fast Fourier Transformation for polynomial multiplication
do t = A[k+m/2]
u = A[k]
A[k] = u+t
A[k+m/2] = u-t
return A
311
Chapter 43. Iterative Fast Fourier Transformation for polynomial multiplication
}
return n;
}
// Iterative FFT function to compute the DFT
// of given coefficient vector
void fft(vector<cd>& a, vector<cd>& A, int log2n)
{
int n = 4;
// bit reversal of the given array
for (unsigned int i = 0; i < n; ++i) {
int rev = bitReverse(i, log2n);
A[i] = a[rev];
}
// j is iota
const complex<double> J(0, 1);
for (int s = 1; s <= log2n; ++s) {
int m = 1 << s; // 2 power s
int m2 = m >> 1; // m2 = m/2 -1
cd w(1, 0);
// principle root of nth complex
// root of unity.
cd wm = exp(J * (PI / m2));
for (int j = 0; j < m2; ++j) {
for (int k = j; k < n; k += m) {
// t = twiddle factor
cd t = w * A[k + m2];
cd u = A[k];
// similar calculating y[k]
A[k] = u + t;
// similar calculating y[k+n/2]
A[k + m2] = u - t;
}
w *= wm;
}
}
}
int main()
{
vector<cd> a{ 1, 2, 3, 4 };
vector<cd> A(4);
312
Chapter 43. Iterative Fast Fourier Transformation for polynomial multiplication
fft(a, A, 2);
for (int i = 0; i < 4; ++i)
cout << A[i] << "\n";
}
Input: 1 2 3 4
Output:
(10, 0)
(-2, -2)
(-2, 0)
(-2, 2)
Source
https://www.geeksforgeeks.org/iterative-fast-fourier-transformation-polynomial-multiplication/
313
Chapter 44
Example:
314
Chapter 44. Iterative Tower of Hanoi
S A D
So, after all these destination pole contains all the in order of size.
After observing above iterations, we can think that after a disk other than the smallest disk
is moved, the next disk to be moved must be the smallest disk because it is the top disk
resting on the spare pole and there are no other choices to move a disk.
C
315
Chapter 44. Iterative Tower of Hanoi
int *array;
};
// function to create a stack of given capacity.
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack =
(struct Stack*) malloc(sizeof(struct Stack));
stack -> capacity = capacity;
stack -> top = -1;
stack -> array =
(int*) malloc(stack -> capacity * sizeof(int));
return stack;
}
// Stack is full when top is equal to the last index
int isFull(struct Stack* stack)
{
return (stack->top == stack->capacity - 1);
}
// Stack is empty when top is equal to -1
int isEmpty(struct Stack* stack)
{
return (stack->top == -1);
}
// Function to add an item to stack. It increases
// top by 1
void push(struct Stack *stack, int item)
{
if (isFull(stack))
return;
stack -> array[++stack -> top] = item;
}
// Function to remove an item from stack. It
// decreases top by 1
int pop(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack -> array[stack -> top--];
}
// Function to implement legal movement between
// two poles
void moveDisksBetweenTwoPoles(struct Stack *src,
316
Chapter 44. Iterative Tower of Hanoi
317
Chapter 44. Iterative Tower of Hanoi
int i, total_num_of_moves;
char s = 'S', d = 'D', a = 'A';
//If number of disks is even, then interchange
//destination pole and auxiliary pole
if (num_of_disks % 2 == 0)
{
char temp = d;
d = a;
a = temp;
}
total_num_of_moves = pow(2, num_of_disks) - 1;
//Larger disks will be pushed first
for (i = num_of_disks; i >= 1; i--)
push(src, i);
for (i = 1; i <= total_num_of_moves; i++)
{
if (i % 3 == 1)
moveDisksBetweenTwoPoles(src, dest, s, d);
else if (i % 3 == 2)
moveDisksBetweenTwoPoles(src, aux, s, a);
else if (i % 3 == 0)
moveDisksBetweenTwoPoles(aux, dest, a, d);
}
}
// Driver Program
int main()
{
// Input: number of disks
unsigned num_of_disks = 3;
struct Stack *src, *dest, *aux;
// Create three stacks of size 'num_of_disks'
// to hold the disks
src = createStack(num_of_disks);
aux = createStack(num_of_disks);
dest = createStack(num_of_disks);
tohIterative(num_of_disks, src, aux, dest);
return 0;
}
318
Chapter 44. Iterative Tower of Hanoi
Java
319
Chapter 44. Iterative Tower of Hanoi
320
Chapter 44. Iterative Tower of Hanoi
}
// Function to implement TOH puzzle
void tohIterative(int num_of_disks, Stack
src, Stack aux, Stack dest)
{
int i, total_num_of_moves;
char s = 'S', d = 'D', a = 'A';
// If number of disks is even, then interchange
// destination pole and auxiliary pole
if (num_of_disks % 2 == 0)
{
char temp = d;
d = a;
a = temp;
}
total_num_of_moves = (int) (Math.pow(2, num_of_disks) - 1);
// Larger disks will be pushed first
for (i = num_of_disks; i >= 1; i--)
push(src, i);
for (i = 1; i <= total_num_of_moves; i++)
{
if (i % 3 == 1)
moveDisksBetweenTwoPoles(src, dest, s, d);
else if (i % 3 == 2)
moveDisksBetweenTwoPoles(src, aux, s, a);
else if (i % 3 == 0)
moveDisksBetweenTwoPoles(aux, dest, a, d);
}
}
// Driver Program to test above functions
public static void main(String[] args)
{
// Input: number of disks
int num_of_disks = 3;
TOH ob = new TOH();
Stack src, dest, aux;
// Create three stacks of size 'num_of_disks'
// to hold the disks
321
Chapter 44. Iterative Tower of Hanoi
src = ob.createStack(num_of_disks);
dest = ob.createStack(num_of_disks);
aux = ob.createStack(num_of_disks);
ob.tohIterative(num_of_disks, src, aux, dest);
}
}
// This code is Contibuted by Sumit Ghosh
Output:
Related Articles
• Recursive Functions
• Tail recursion
• Quiz on Recursion
References:
http://en.wikipedia.org/wiki/Tower_of_Hanoi#Iterative_solution
This article is contributed by Anand Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : VIKASGUPTA1127
Source
https://www.geeksforgeeks.org/iterative-tower-of-hanoi/
322
Chapter 45
Syntax :
Advantage :
parallelSort() method uses concept of MultiThreading which makes the sorting faster as
compared to normal sorting method.
323
Chapter 45. Java 8 | Arrays parallelSort() method with Examples
Example
Below are the program that will illustrate the use of Arrays.parallelSort():
Program 1: To demonstrate use of Parallel Sort
324
Chapter 45. Java 8 | Arrays parallelSort() method with Examples
Output:
Unsorted Array: 9 8 7 6 3 1
Sorted Array: 1 3 6 7 8 9
325
Chapter 45. Java 8 | Arrays parallelSort() method with Examples
Output:
326
Chapter 45. Java 8 | Arrays parallelSort() method with Examples
.
For iteration number: 99
Start and End Time in Serial (in ns): 3951050723541:3951050731520
Time taken by Serial Sort(in ns): 7979
Start and End Time in parallel (in ns): 3951050754238:3951050756130
Time taken by Parallel Sort(in ns): 1892
Note : Different time intervals will be printed But parallel sort will be done before normal
sort.
Environment: 2.6 GHz Intel Core i7, java version 8
Source
https://www.geeksforgeeks.org/java-8-arrays-parallelsort-method-with-examples/
327
Chapter 46
Input : Array 1 - 2 3 6 7 9
Array 2 - 1 4 8 10
k = 5
Output : 6
Explanation: The final sorted array would be -
1, 2, 3, 4, 6, 7, 8, 9, 10
The 5th element of this array is 6.
Input : Array 1 - 100 112 256 349 770
Array 2 - 72 86 113 119 265 445 892
k = 7
Output : 256
Explanation: Final sorted array is -
72, 86, 100, 112, 113, 119, 256, 265, 349, 445, 770, 892
7th element of this array is 256.
Basic Approach
Since we are given two sorted arrays, we can use merging technique to get the final merged
array. From this, we simply go to the k’th index.
C++
328
Chapter 46. K-th Element of Two Sorted Arrays
Java
329
Chapter 46. K-th Element of Two Sorted Arrays
}
while (i < m)
sorted1[d++] = arr1[i++];
while (j < n)
sorted1[d++] = arr2[j++];
return sorted1[k - 1];
}
// main function
public static void main (String[] args)
{
int arr1[] = {2, 3, 6, 7, 9};
int arr2[] = {1, 4, 8, 10};
int k = 5;
System.out.print(kth(arr1, arr2, 5, 4, k));
}
}
/* This code is contributed by Harsh Agarwal */
Python3
330
Chapter 46. K-th Element of Two Sorted Arrays
j += 1
return sorted1[k - 1]
# driver code
arr1 = [2, 3, 6, 7, 9]
arr2 = [1, 4, 8, 10]
k = 5;
print(kth(arr1, arr2, 5, 4, k))
# This code is contributed by Smitha Dinesh Semwal
C#
331
Chapter 46. K-th Element of Two Sorted Arrays
PHP
<?php
// Program to find kth
// element from two
// sorted arrays
function kth($arr1, $arr2,
$m, $n, $k)
{
$sorted1[$m + $n] = 0;
$i = 0;
$j = 0;
$d = 0;
while ($i < $m && $j < $n)
{
if ($arr1[$i] < $arr2[$j])
$sorted1[$d++] = $arr1[$i++];
else
$sorted1[$d++] = $arr2[$j++];
}
while ($i < $m)
$sorted1[$d++] = $arr1[$i++];
while ($j < $n)
$sorted1[$d++] = $arr2[$j++];
return $sorted1[$k - 1];
}
// Driver Code
$arr1 = array(2, 3, 6, 7, 9);
$arr2 = array(1, 4, 8, 10);
$k = 5;
echo kth($arr1, $arr2, 5, 4, $k);
// This code is contributed
// by ChitraNayal
?>
Output:
332
Chapter 46. K-th Element of Two Sorted Arrays
is yes. By using a divide and conquer approach, similar to the one used in binary search,
we can attempt to find the k’th element in a more efficient way.
Explanation:
We compare the middle elements of arrays arr1 and arr2,
let us call these indices mid1 and mid2 respectively.
C++
333
Chapter 46. K-th Element of Two Sorted Arrays
int main()
{
int arr1[5] = {2, 3, 6, 7, 9};
int arr2[4] = {1, 4, 8, 10};
int k = 5;
cout << kth(arr1, arr2, arr1 + 5, arr2 + 4, k - 1);
return 0;
}
Output:
Note that in the above code, k is 0 indexed, which means if we want a k that’s 1 indexed,
we have to subtract 1 when passing it to the function.
Time Complexity: O(log n + log m)
Divide And Conquer Approach 2
While the above implementation is very efficient, we can still get away with making it more
efficient. Instead of dividing the array into segments of n / 2 and m / 2 then recursing, we
can divide them both by k / 2 and recurse. Below implementation displays this.
Explanation:
Instead of comparing the middle element of the arrays,
we compare the k / 2th element.
Let arr1 and arr2 be the arrays.
Now, if arr1[k / 2] arr1[1]
New subproblem:
Array 1 - 6 7 9
Array 2 - 1 4 8 10
k = 5 - 2 = 3
floor(k / 2) = 1
arr1[1] = 6
arr2[1] = 1
arr1[1] > arr2[1]
New subproblem:
Array 1 - 6 7 9
Array 2 - 4 8 10
k = 3 - 1 = 2
floor(k / 2) = 1
arr1[1] = 6
334
Chapter 46. K-th Element of Two Sorted Arrays
arr2[1] = 4
arr1[1] > arr2[1]
New subproblem:
Array 1 - 6 7 9
Array 2 - 8 10
k = 2 - 1 = 1
C++
335
Chapter 46. K-th Element of Two Sorted Arrays
Output:
336
Chapter 46. K-th Element of Two Sorted Arrays
+ n) < log(mn). Thus this algorithm slightly outperforms the previous algorithm.Also see
another simple implemented log k approach suggested by Raj Kumar.
C++
337
Chapter 46. K-th Element of Two Sorted Arrays
return 0;
}
// This code is contributed by Raj Kumar
Source
https://www.geeksforgeeks.org/k-th-element-two-sorted-arrays/
338
Chapter 47
Karatsuba algorithm for fast multiplication using Divide and Conquer algorithm - Geeks-
forGeeks
Given two binary strings that represent value of two integers, find the product of two strings.
For example, if the first bit string is “1100” and second bit string is “1010”, output should
be 120.
For simplicity, let the length of two strings be same and be n.
A Naive Approach is to follow the process we study in school. One by one take all bits of
second number and multiply it with all bits of first number. Finally add all multiplications.
This algorithm takes O(n^2) time.
339
Chapter 47. Karatsuba algorithm for fast multiplication using Divide and Conquer
algorithm
Using Divide and Conquer, we can multiply two integers in less time complexity. We
divide the given numbers in two halves. Let the given numbers be X and Y.
For simplicity let us assume that n is even
If we take a look at the above formula, there are four multiplications of size n/2, so we
basically divided the problem of size n into for sub-problems of size n/2. But that doesn’t
help because solution of recurrence T(n) = 4T(n/2) + O(n) is O(n^2). The tricky part of
this algorithm is to change the middle two terms to some other form so that only one extra
multiplication would be sufficient. The following is tricky expression for middle two terms.
With above trick, the recurrence becomes T(n) = 3T(n/2) + O(n) and solution of this
recurrence is O(n1.59 ).
What if the lengths of input strings are different and are not even? To handle the different
length case, we append 0’s in the beginning. To handle odd length, we put floor(n/2) bits
in left half and ceil(n/2) bits in right half. So the expression for XY changes to following.
The above algorithm is called Karatsuba algorithm and it can be used for any base.
Following is C++ implementation of above algorithm.
340
Chapter 47. Karatsuba algorithm for fast multiplication using Divide and Conquer
algorithm
341
Chapter 47. Karatsuba algorithm for fast multiplication using Divide and Conquer
algorithm
// A utility function to multiply single bits of strings a and b
int multiplyiSingleBit(string a, string b)
{ return (a[0] - '0')*(b[0] - '0'); }
// The main function that multiplies two bit strings X and Y and returns
// result as long integer
long int multiply(string X, string Y)
{
// Find the maximum of lengths of x and Y and make length
// of smaller string same as that of larger string
int n = makeEqualLength(X, Y);
// Base cases
if (n == 0) return 0;
if (n == 1) return multiplyiSingleBit(X, Y);
int fh = n/2; // First half of string, floor(n/2)
int sh = (n-fh); // Second half of string, ceil(n/2)
// Find the first half and second half of first string.
// Refer http://goo.gl/lLmgn for substr method
string Xl = X.substr(0, fh);
string Xr = X.substr(fh, sh);
// Find the first half and second half of second string
string Yl = Y.substr(0, fh);
string Yr = Y.substr(fh, sh);
// Recursively calculate the three products of inputs of size n/2
long int P1 = multiply(Xl, Yl);
long int P2 = multiply(Xr, Yr);
long int P3 = multiply(addBitStrings(Xl, Xr), addBitStrings(Yl, Yr));
// Combine the three products to get the final result.
return P1*(1<<(2*sh)) + (P3 - P1 - P2)*(1<<sh) + P2;
}
// Driver program to test aboev functions
int main()
{
printf ("%ld\n", multiply("1100", "1010"));
printf ("%ld\n", multiply("110", "1010"));
printf ("%ld\n", multiply("11", "1010"));
printf ("%ld\n", multiply("1", "1010"));
printf ("%ld\n", multiply("0", "1010"));
printf ("%ld\n", multiply("111", "111"));
printf ("%ld\n", multiply("11", "11"));
342
Chapter 47. Karatsuba algorithm for fast multiplication using Divide and Conquer
algorithm
Output:
120
60
30
10
0
49
9
Source
https://www.geeksforgeeks.org/karatsuba-algorithm-for-fast-multiplication-using-divide-and-conquer-algorithm/
343
Chapter 48
A simple solution is to one by one consider all bars as starting points and calculate area of
344
Chapter 48. Largest Rectangular Area in a Histogram | Set 1
all rectangles starting with every bar. Finally return maximum of all possible areas. Time
complexity of this solution would be O(n^2).
We can use Divide and Conquer to solve this in O(nLogn) time. The idea is to find the
minimum value in the given array. Once we have index of the minimum value, the max area
is maximum of following three values.
a) Maximum area in left side of minimum value (Not including the min value)
b) Maximum area in right side of minimum value (Not including the min value)
c) Number of bars multiplied by minimum value.
The areas in left and right of minimum value bar can be calculated recursively. If we
use linear search to find the minimum value, then the worst case time complexity of this
algorithm becomes O(n^2). In worst case, we always have (n-1) elements in one side and 0
elements in other side and if the finding minimum takes O(n) time, we get the recurrence
similar to worst case of Quick Sort.
How to find the minimum efficiently? Range Minimum Query using Segment Tree can be
used for this. We build segment tree of the given histogram heights. Once the segment
tree is built, all range minimum queries take O(Logn) time. So over all complexity of the
algorithm becomes.
Overall Time = Time to build Segment Tree + Time to recursively find maximum area
Time to build segment tree is O(n). Let the time to recursively find max area be T(n). It
can be written as following.
T(n) = O(Logn) + T(n-1)
The solution of above recurrence is O(nLogn). So overall time is O(n) + O(nLogn) which
is O(nLogn).
Following is C++ implementation of the above algorithm.
345
Chapter 48. Largest Rectangular Area in a Histogram | Set 1
/* A recursive function to get the index of minimum value in a given range of
indexes. The following are parameters for this function.
hist --> Input array for which segment tree is built
st --> Pointer to segment tree
index --> Index of current node in the segment tree. Initially 0 is
passed as root is always at index 0
ss & se --> Starting and ending indexes of the segment represented by
current node, i.e., st[index]
qs & qe --> Starting and ending indexes of query range */
int RMQUtil(int *hist, int *st, int ss, int se, int qs, int qe, int index)
{
// If segment of this node is a part of given range, then return the
// min of the segment
if (qs <= ss && qe >= se)
return st[index];
// If segment of this node is outside the given range
if (se < qs || ss > qe)
return -1;
// If a part of this segment overlaps with the given range
int mid = getMid(ss, se);
return minVal(hist, RMQUtil(hist, st, ss, mid, qs, qe, 2*index+1),
RMQUtil(hist, st, mid+1, se, qs, qe, 2*index+2));
}
// Return index of minimum element in range from index qs (quey start) to
// qe (query end). It mainly uses RMQUtil()
int RMQ(int *hist, int *st, int n, int qs, int qe)
{
// Check for erroneous input values
if (qs < 0 || qe > n-1 || qs > qe)
{
cout << "Invalid Input";
return -1;
}
return RMQUtil(hist, st, 0, n-1, qs, qe, 0);
}
// A recursive function that constructs Segment Tree for hist[ss..se].
// si is index of current node in segment tree st
int constructSTUtil(int hist[], int ss, int se, int *st, int si)
{
// If there is one element in array, store it in current node of
// segment tree and return
346
Chapter 48. Largest Rectangular Area in a Histogram | Set 1
347
Chapter 48. Largest Rectangular Area in a Histogram | Set 1
// The main function to find max area
int getMaxArea(int hist[], int n)
{
// Build segment tree from given array. This takes
// O(n) time
int *st = constructST(hist, n);
// Use recursive utility function to find the
// maximum area
return getMaxAreaRec(hist, st, n, 0, n-1);
}
// Driver program to test above functions
int main()
{
int hist[] = {6, 1, 5, 4, 5, 2, 6};
int n = sizeof(hist)/sizeof(hist[0]);
cout << "Maximum area is " << getMaxArea(hist, n);
return 0;
}
Output:
Maximum area is 12
This problem can be solved in linear time. See below set 2 for linear time solution.
Linear time solution for Largest Rectangular Area in a Histogram
Source
https://www.geeksforgeeks.org/largest-rectangular-area-in-a-histogram-set-1/
348
Chapter 49
We have discussed word by word matching and character by character matching algorithms.
In this algorithm, a divide and conquer approach is discussed. We first divide the arrays of
string into two parts. Then we do the same for left part and after that for the right part.
We will do it until and unless all the strings become of length 1. Now after that, we will
start conquering by returning the common prefix of the left and the right strings.
The algorithm will be clear using the below illustration. We consider our strings as –
“geeksforgeeks”, “geeks”, “geek”, “geezer”
349
Chapter 49. Longest Common Prefix using Divide and Conquer Algorithm
350
Chapter 49. Longest Common Prefix using Divide and Conquer Algorithm
result.push_back(str1[i]);
}
return (result);
}
// A Divide and Conquer based function to find the
// longest common prefix. This is similar to the
// merge sort technique
string commonPrefix(string arr[], int low, int high)
{
if (low == high)
return (arr[low]);
if (high > low)
{
// Same as (low + high)/2, but avoids overflow for
// large low and high
int mid = low + (high - low) / 2;
string str1 = commonPrefix(arr, low, mid);
string str2 = commonPrefix(arr, mid+1, high);
return (commonPrefixUtil(str1, str2));
}
}
// Driver program to test above function
int main()
{
string arr[] = {"geeksforgeeks", "geeks",
"geek", "geezer"};
int n = sizeof (arr) / sizeof (arr[0]);
string ans = commonPrefix(arr, 0, n-1);
if (ans.length())
cout << "The longest common prefix is "
<< ans;
else
cout << "There is no common prefix";
return (0);
}
Output :
Time Complexity : Since we are iterating through all the characters of all the strings, so
351
Chapter 49. Longest Common Prefix using Divide and Conquer Algorithm
N = Number of strings
M = Length of the largest string string
Auxiliary Space : To store the longest prefix string we are allocating space which is O(M
Log N).
Source
https://www.geeksforgeeks.org/longest-common-prefix-using-divide-and-conquer-algorithm/
352
Chapter 50
C++
// A Divide and Conquer based program for maximum subarray sum problem
#include <stdio.h>
353
Chapter 50. Maximum Subarray Sum using Divide and Conquer algorithm
#include <limits.h>
// A utility funtion to find maximum of two integers
int max(int a, int b) { return (a > b)? a : b; }
// A utility funtion to find maximum of three integers
int max(int a, int b, int c) { return max(max(a, b), c); }
// Find the maximum possible sum in arr[] auch that arr[m] is part of it
int maxCrossingSum(int arr[], int l, int m, int h)
{
// Include elements on left of mid.
int sum = 0;
int left_sum = INT_MIN;
for (int i = m; i >= l; i--)
{
sum = sum + arr[i];
if (sum > left_sum)
left_sum = sum;
}
// Include elements on right of mid
sum = 0;
int right_sum = INT_MIN;
for (int i = m+1; i <= h; i++)
{
sum = sum + arr[i];
if (sum > right_sum)
right_sum = sum;
}
// Return sum of elements on left and right of mid
return left_sum + right_sum;
}
// Returns sum of maxium sum subarray in aa[l..h]
int maxSubArraySum(int arr[], int l, int h)
{
// Base Case: Only one element
if (l == h)
return arr[l];
// Find middle point
int m = (l + h)/2;
/* Return maximum of following three possible cases
a) Maximum subarray sum in left half
b) Maximum subarray sum in right half
354
Chapter 50. Maximum Subarray Sum using Divide and Conquer algorithm
c) Maximum subarray sum such that the subarray crosses the midpoint */
return max(maxSubArraySum(arr, l, m),
maxSubArraySum(arr, m+1, h),
maxCrossingSum(arr, l, m, h));
}
/*Driver program to test maxSubArraySum*/
int main()
{
int arr[] = {2, 3, 4, 5, 7};
int n = sizeof(arr)/sizeof(arr[0]);
int max_sum = maxSubArraySum(arr, 0, n-1);
printf("Maximum contiguous sum is %dn", max_sum);
getchar();
return 0;
}
Java
355
Chapter 50. Maximum Subarray Sum using Divide and Conquer algorithm
right_sum = sum;
}
// Return sum of elements on left
// and right of mid
return left_sum + right_sum;
}
// Returns sum of maxium sum subarray
// in aa[l..h]
static int maxSubArraySum(int arr[], int l,
int h)
{
// Base Case: Only one element
if (l == h)
return arr[l];
// Find middle point
int m = (l + h)/2;
/* Return maximum of following three
possible cases:
a) Maximum subarray sum in left half
b) Maximum subarray sum in right half
c) Maximum subarray sum such that the
subarray crosses the midpoint */
return Math.max(Math.max(maxSubArraySum(arr, l, m),
maxSubArraySum(arr, m+1, h)),
maxCrossingSum(arr, l, m, h));
}
/* Driver program to test maxSubArraySum */
public static void main(String[] args)
{
int arr[] = {2, 3, 4, 5, 7};
int n = arr.length;
int max_sum = maxSubArraySum(arr, 0, n-1);
System.out.println("Maximum contiguous sum is "+
max_sum);
}
}
// This code is contributed by Prerna Saini
Python3
356
Chapter 50. Maximum Subarray Sum using Divide and Conquer algorithm
# Find the maximum possible sum in
# arr[] auch that arr[m] is part of it
def maxCrossingSum(arr, l, m, h) :
# Include elements on left of mid.
sm = 0; left_sum = -10000
for i in range(m, l-1, -1) :
sm = sm + arr[i]
if (sm > left_sum) :
left_sum = sm
# Include elements on right of mid
sm = 0; right_sum = -1000
for i in range(m + 1, h + 1) :
sm = sm + arr[i]
if (sm > right_sum) :
right_sum = sm
# Return sum of elements on left and right of mid
return left_sum + right_sum;
# Returns sum of maxium sum subarray in aa[l..h]
def maxSubArraySum(arr, l, h) :
# Base Case: Only one element
if (l == h) :
return arr[l]
# Find middle point
m = (l + h) // 2
# Return maximum of following three possible cases
# a) Maximum subarray sum in left half
# b) Maximum subarray sum in right half
# c) Maximum subarray sum such that the
# subarray crosses the midpoint
return max(maxSubArraySum(arr, l, m),
maxSubArraySum(arr, m+1, h),
maxCrossingSum(arr, l, m, h))
357
Chapter 50. Maximum Subarray Sum using Divide and Conquer algorithm
# Driver Code
arr = [2, 3, 4, 5, 7]
n = len(arr)
max_sum = maxSubArraySum(arr, 0, n-1)
print("Maximum contiguous sum is ", max_sum)
# This code is contributed by Nikita Tiwari.
C#
358
Chapter 50. Maximum Subarray Sum using Divide and Conquer algorithm
Output :
359
Chapter 50. Maximum Subarray Sum using Divide and Conquer algorithm
Tree method or Master method. It falls in case II of Master Method and solution of the
recurrence is Θ(nLogn).
The Kadane’s Algorithm for this problem takes O(n) time. Therefore the Kadane’s algo-
rithm is better than the Divide and Conquer approach, but this problem can be considered
as a good example to show power of Divide and Conquer. The above simple approach where
we divide the array in two halves, reduces the time complexity from O(n^2) to O(nLogn).
References:
Introduction to Algorithms by Clifford Stein, Thomas H. Cormen, Charles E. Leiserson,
Ronald L.
Source
https://www.geeksforgeeks.org/maximum-subarray-sum-using-divide-and-conquer-algorithm/
360
Chapter 51
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 respec-
tively. 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)
361
Chapter 51. Maximum and minimum of an array using minimum number of comparisons
struct pair
{
int min;
int max;
};
struct pair getMinMax(int arr[], int n)
{
struct pair minmax;
int i;
/*If there is only one element then return it as min and max both*/
if (n == 1)
{
minmax.max = arr[0];
minmax.min = arr[0];
return minmax;
}
/* If there are more than one elements, then initialize min
and max*/
if (arr[0] > arr[1])
{
minmax.max = arr[0];
minmax.min = arr[1];
}
else
{
minmax.max = arr[1];
minmax.min = arr[0];
}
for (i = 2; i<n; i++)
{
if (arr[i] > minmax.max)
minmax.max = arr[i];
else if (arr[i] < minmax.min)
minmax.min = arr[i];
}
return minmax;
}
/* Driver program to test above function */
int main()
{
int arr[] = {1000, 11, 445, 1, 330, 3000};
362
Chapter 51. Maximum and minimum of an array using minimum number of comparisons
int arr_size = 6;
struct pair minmax = getMinMax (arr, arr_size);
printf("nMinimum element is %d", minmax.min);
printf("nMaximum element is %d", minmax.max);
getchar();
}
Implementation
363
Chapter 51. Maximum and minimum of an array using minimum number of comparisons
364
Chapter 51. Maximum and minimum of an array using minimum number of comparisons
T(n) = 2T(n/2) + 2
T(n) = 3n/2 -2
Thus, the approach does 3n/2 -2 comparisons if n is a power of 2. And it does more than
3n/2 -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.
#include<stdio.h>
/* 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;
365
Chapter 51. Maximum and minimum of an array using minimum number of comparisons
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 has odd number of elements then
initialize the first element as minimum and
maximum */
else
{
minmax.min = arr[0];
minmax.max = arr[0];
i = 1; /* 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];
}
366
Chapter 51. Maximum and minimum of an array using minimum number of comparisons
If n is odd: 3*(n-1)/2
If n is even: 1 Initial comparison for initializing min and max,
and 3(n-2)/2 comparisons for rest of the elements
= 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.
Improved By : kamleshbhalui
Source
https://www.geeksforgeeks.org/maximum-and-minimum-in-an-array/
367
Chapter 52
368
Chapter 52. Median of two sorted arrays of different sizes
sub-cases.
…2.1 If A[0] is smaller than 10, the median is average of 10 and 12.
…2.2 If A[0] lies between 10 and 12, the median is average of A[0] and 12.
…2.3 If A[0] lies between 12 and 15, the median is average of 12 and A[0].
…2.4 If A[0] is greater than 15, the median is average of 12 and 15.
In all the sub-cases, we find that 12 is fixed. So, we need to find the median of B[ M / 2 –
1 ], B[ M / 2 + 1], A[ 0 ] and take its average with B[ M / 2 ].
Case 3: N = 1, M is even
Let B[4] = {5, 10, 12, 15}
First find the middle items in B[], which are 10 and 12 in above example. There are following
3 sub-cases.
…3.1 If A[0] is smaller than 10, the median is 10.
…3.2 If A[0] lies between 10 and 12, the median is A[0].
…3.3 If A[0] is greater than 12, the median is 12.
So, in this case, find the median of three elements B[ M / 2 – 1 ], B[ M / 2] and A[ 0 ].
Case 4: N = 2, M = 2
There are four elements in total. So we find the median of 4 elements.
Case 5: N = 2, M is odd
Let B[5] = {5, 10, 12, 15, 20}
The median is given by median of following three elements: B[M/2], max(A[0], B[M/2 – 1]),
min(A[1], B[M/2 + 1]).
Case 6: N = 2, M is even
Let B[4] = {5, 10, 12, 15}
The median is given by median of following four elements: B[M/2], B[M/2 – 1], max(A[0],
B[M/2 – 2]), min(A[1], B[M/2 + 1])
Remaining Cases:
Once we have handled the above base cases, following is the remaining process.
1) Find the middle item of A[] and middle item of B[].
…..1.1) If the middle item of A[] is greater than middle item of B[], ignore the last half of
A[], let length of ignored part is idx. Also, cut down B[] by idx from the start.
…..1.2) else, ignore the first half of A[], let length of ignored part is idx. Also, cut down B[]
by idx from the last.
Following is implementation of the above approach.
C++
369
Chapter 52. Median of two sorted arrays of different sizes
// A utility function to find median of three integers
float MO3(int a, int b, int c)
{
return a + b + c - max(a, max(b, c))
- min(a, min(b, c));
}
// A utility function to find median of four integers
float MO4(int a, int b, int c, int d)
{
int Max = max( a, max( b, max( c, d ) ) );
int Min = min( a, min( b, min( c, d ) ) );
return ( a + b + c + d - Max - Min ) / 2.0;
}
// Utility function to find median of single array
float medianSingle(int arr[], int n)
{
if (n == 0)
return -1;
if (n%2 == 0)
return (double)(arr[n/2] + arr[n/2-1])/2;
return arr[n/2];
}
// This function assumes that N is smaller than or equal to M
// This function returns -1 if both arrays are empty
float findMedianUtil( int A[], int N, int B[], int M )
{
// If smaller array is empty, return median from second array
if (N == 0)
return medianSingle(B, M);
// If the smaller array has only one element
if (N == 1)
{
// Case 1: If the larger array also has one element,
// simply call MO2()
if (M == 1)
return MO2(A[0], B[0]);
// Case 2: If the larger array has odd number of elements,
// then consider the middle 3 elements of larger array and
// the only element of smaller array. Take few examples
// like following
// A = {9}, B[] = {5, 8, 10, 20, 30} and
// A[] = {1}, B[] = {5, 8, 10, 20, 30}
370
Chapter 52. Median of two sorted arrays of different sizes
if (M & 1)
return MO2( B[M/2], MO3(A[0], B[M/2 - 1], B[M/2 + 1]) );
// Case 3: If the larger array has even number of element,
// then median will be one of the following 3 elements
// ... The middle two elements of larger array
// ... The only element of smaller array
return MO3( B[M/2], B[M/2 - 1], A[0] );
}
// If the smaller array has two elements
else if (N == 2)
{
// Case 4: If the larger array also has two elements,
// simply call MO4()
if (M == 2)
return MO4(A[0], A[1], B[0], B[1]);
// Case 5: If the larger array has odd number of elements,
// then median will be one of the following 3 elements
// 1. Middle element of larger array
// 2. Max of first element of smaller array and element
// just before the middle in bigger array
// 3. Min of second element of smaller array and element
// just after the middle in bigger array
if (M & 1)
return MO3 ( B[M/2],
max(A[0], B[M/2 - 1]),
min(A[1], B[M/2 + 1])
);
// Case 6: If the larger array has even number of elements,
// then median will be one of the following 4 elements
// 1) & 2) The middle two elements of larger array
// 3) Max of first element of smaller array and element
// just before the first middle element in bigger array
// 4. Min of second element of smaller array and element
// just after the second middle in bigger array
return MO4 ( B[M/2],
B[M/2 - 1],
max( A[0], B[M/2 - 2] ),
min( A[1], B[M/2 + 1] )
);
}
int idxA = ( N - 1 ) / 2;
int idxB = ( M - 1 ) / 2;
371
Chapter 52. Median of two sorted arrays of different sizes
PHP
<?php
// A PHP program to find median
// of two sorted arrays of
// unequal sizes
// A utility function to
// find median of two integers
function MO2($a, $b)
{
return ($a + $b) / 2.0;
}
372
Chapter 52. Median of two sorted arrays of different sizes
373
Chapter 52. Median of two sorted arrays of different sizes
if ($M == 1)
return MO2($A[0], $B[0]);
// Case 2: If the larger array
// has odd number of elements,
// then consider the middle 3
// elements of larger array and
// the only element of smaller
// array. Take few examples
// like following
// $A = array(9),
// $B = array(5, 8, 10, 20, 30)
// and $A = array(1),
// $B = array(5, 8, 10, 20, 30)
if ($M & 1)
return MO2($B[$M / 2], $MO3($A[0],
$B[$M / 2 - 1],
$B[$M / 2 + 1]));
// Case 3: If the larger array
// has even number of element,
// then median will be one of
// the following 3 elements
// ... The middle two elements
// of larger array
// ... The only element of
// smaller array
return MO3($B[$M / 2],
$B[$M / 2 - 1], $A[0]);
}
// If the smaller array
// has two elements
else if ($N == 2)
{
// Case 4: If the larger
// array also has two elements,
// simply call MO4()
if ($M == 2)
return MO4($A[0], $A[1],
$B[0], $B[1]);
// Case 5: If the larger array
// has odd number of elements,
// then median will be one of
// the following 3 elements
// 1. Middle element of
// larger array
374
Chapter 52. Median of two sorted arrays of different sizes
375
Chapter 52. Median of two sorted arrays of different sizes
Output:
10
Source
https://www.geeksforgeeks.org/median-of-two-sorted-arrays-of-different-sizes/
376
Chapter 53
Note : Since size of the set for which we are looking for median is even (2n), we need take
average of middle two numbers and return floor of the average.
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 aver-
age of the elements at indexes n-1 and n in the merged array. See the below implementation.
C++
377
Chapter 53. Median of two sorted arrays of same size
378
Chapter 53. Median of two sorted arrays of same size
if (ar1[i] < ar2[j])
{
/* Store the prev median */
m1 = m2;
m2 = ar1[i];
i++;
}
else
{
/* Store the prev median */
m1 = m2;
m2 = ar2[j];
j++;
}
}
return (m1 + m2)/2;
}
// Driver Code
int main()
{
int ar1[] = {1, 12, 15, 26, 38};
int ar2[] = {2, 13, 17, 30, 45};
int n1 = sizeof(ar1) / sizeof(ar1[0]);
int n2 = sizeof(ar2) / sizeof(ar2[0]);
if (n1 == n2)
cout << "Median is "
<< getMedian(ar1, ar2, n1) ;
else
cout << "Doesn't work for arrays"
<< " of unequal size" ;
getchar();
return 0;
}
// This code is contributed
// by Shivi_Aggarwal
379
Chapter 53. Median of two sorted arrays of same size
380
Chapter 53. Median of two sorted arrays of same size
}
/* Driver program to test above function */
int main()
{
int ar1[] = {1, 12, 15, 26, 38};
int ar2[] = {2, 13, 17, 30, 45};
int n1 = sizeof(ar1)/sizeof(ar1[0]);
int n2 = sizeof(ar2)/sizeof(ar2[0]);
if (n1 == n2)
printf("Median is %d", getMedian(ar1, ar2, n1));
else
printf("Doesn't work for arrays of unequal size");
getchar();
return 0;
}
Java
381
Chapter 53. Median of two sorted arrays of same size
/* 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])
{
/* Store the prev median */
m1 = m2;
m2 = ar1[i];
i++;
}
else
{
/* Store the prev median */
m1 = m2;
m2 = ar2[j];
j++;
}
}
return (m1 + m2)/2;
}
/* Driver program to test above function */
public static void main (String[] args)
{
int ar1[] = {1, 12, 15, 26, 38};
int ar2[] = {2, 13, 17, 30, 45};
int n1 = ar1.length;
int n2 = ar2.length;
if (n1 == n2)
System.out.println("Median is " +
getMedian(ar1, ar2, n1));
else
System.out.println("arrays are of unequal size");
}
}
Python3
382
Chapter 53. Median of two sorted arrays of same size
383
Chapter 53. Median of two sorted arrays of same size
C#
384
Chapter 53. Median of two sorted arrays of same size
PHP
<?php
// A Simple Merge based O(n) solution
385
Chapter 53. Median of two sorted arrays of same size
386
Chapter 53. Median of two sorted arrays of same size
}
else
{
// Store the prev median
$m1 = $m2;
$m2 = $ar2[$j];
$j++;
}
}
return ($m1 + $m2) / 2;
}
// Driver Code
$ar1 = array(1, 12, 15, 26, 38);
$ar2 = array(2, 13, 17, 30, 45);
$n1 = sizeof($ar1);
$n2 = sizeof($ar2);
if ($n1 == $n2)
echo("Median is " .
getMedian($ar1, $ar2, $n1));
else
echo("Doesn't work for arrays".
"of unequal size");
// This code is contributed by Ajit.
?>
Output :
Median is 16
387
Chapter 53. Median of two sorted arrays of same size
Examples :
m1 = 26 m2 = 13.
Implementation :
C++
388
Chapter 53. Median of two sorted arrays of same size
389
Chapter 53. Median of two sorted arrays of same size
{
if (n % 2 == 0)
return getMedian(ar1 + n / 2 - 1,
ar2, n - n / 2 + 1);
return getMedian(ar1 + n / 2,
ar2, n - n / 2);
}
/* if m1 > m2 then median must
exist in ar1[....m1] and
ar2[m2...] */
if (n % 2 == 0)
return getMedian(ar2 + n / 2 - 1,
ar1, n - n / 2 + 1);
return getMedian(ar2 + n / 2,
ar1, n - n / 2);
}
/* Function to get median
of a sorted 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];
}
// Driver code
int main()
{
int ar1[] = {1, 2, 3, 6};
int ar2[] = {4, 6, 8, 10};
int n1 = sizeof(ar1) /
sizeof(ar1[0]);
int n2 = sizeof(ar2) /
sizeof(ar2[0]);
if (n1 == n2)
cout << "Median is "
<< getMedian(ar1, ar2, n1);
else
cout << "Doesn't work for arrays "
<< "of unequal size";
return 0;
}
// This code is contributed
390
Chapter 53. Median of two sorted arrays of same size
// by Shivi_Aggarwal
391
Chapter 53. Median of two sorted arrays of same size
Output :
Median is 5
Source
https://www.geeksforgeeks.org/median-of-two-sorted-arrays/
392
Chapter 54
Merge Sort
MergeSort(arr[], l, r)
If r > l
1. Find the middle point to divide the array into two halves:
middle m = (l+r)/2
2. Call mergeSort for first half:
Call mergeSort(arr, l, m)
3. Call mergeSort for second half:
Call mergeSort(arr, m+1, r)
4. Merge the two halves sorted in step 2 and 3:
Call merge(arr, l, m, r)
The following diagram from wikipedia shows the complete merge sort process for an example
array {38, 27, 43, 3, 9, 82, 10}. If we take a closer look at the diagram, we can see that
the array is recursively divided in two halves till the size becomes 1. Once the size becomes
1, the merge processes comes into action and starts merging arrays back till the complete
array is merged.
393
Chapter 54. Merge Sort
C/C++
394
Chapter 54. Merge Sort
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
/* create temp arrays */
int L[n1], R[n2];
/* Copy data to temp arrays L[] and R[] */
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1+ j];
/* Merge the temp arrays back into arr[l..r]*/
i = 0; // Initial index of first subarray
j = 0; // Initial index of second subarray
k = l; // Initial index of merged subarray
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
/* Copy the remaining elements of L[], if there
are any */
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
/* Copy the remaining elements of R[], if there
are any */
while (j < n2)
{
arr[k] = R[j];
j++;
395
Chapter 54. Merge Sort
k++;
}
}
/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r)
{
if (l < r)
{
// Same as (l+r)/2, but avoids overflow for
// large l and h
int m = l+(r-l)/2;
// Sort first and second halves
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
}
/* UTILITY FUNCTIONS */
/* Function to print an array */
void printArray(int A[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", A[i]);
printf("\n");
}
/* Driver program to test above functions */
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
int arr_size = sizeof(arr)/sizeof(arr[0]);
printf("Given array is \n");
printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
printf("\nSorted array is \n");
printArray(arr, arr_size);
return 0;
}
396
Chapter 54. Merge Sort
Java
397
Chapter 54. Merge Sort
398
Chapter 54. Merge Sort
System.out.println("Given Array");
printArray(arr);
MergeSort ob = new MergeSort();
ob.sort(arr, 0, arr.length-1);
System.out.println("\nSorted array");
printArray(arr);
}
}
/* This code is contributed by Rajat Mishra */
Python
399
Chapter 54. Merge Sort
C#
400
Chapter 54. Merge Sort
class MergeSort {
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int[] arr, int l,
int m, int r)
{
// Find sizes of two subarrays
// to be merged
int n1 = m - l + 1;
int n2 = r - m;
// Create temp arrays
int[] L = new int [n1];
int[] R = new int [n2];
// Copy data to temp arrays
int i, j;
for (i = 0; i < n1; ++i)
L[i] = arr[l + i];
for (j = 0; j < n2; ++j)
R[j] = arr[m + 1+ j];
// Merge the temp arrays
// Initial indexes of first
// and second subarrays
i = 0;
j = 0;
// Initial index of merged
// subarry array
int k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
401
Chapter 54. Merge Sort
j++;
}
k++;
}
// Copy remaining elements
// of L[] if any
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
// Copy remaining elements
// of R[] if any
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}
// Main function that sorts
// arr[l..r] using merge()
void sort(int[] arr, int l, int r)
{
if (l < r)
{
// Find the middle point
int m = (l + r) / 2;
// Sort first and
// second halves
sort(arr, l, m);
sort(arr , m + 1, r);
// Merge the sorted halves
merge(arr, l, m, r);
}
}
// A utility function to print
// array of size n
static void printArray(int[] arr)
{
int n = arr.Length;
402
Chapter 54. Merge Sort
for (int i = 0; i < n; ++i)
Console.Write(arr[i] + " ");
Console.Write("\n");
}
// Driver Code
public static void Main()
{
int[] arr = {12, 11, 13, 5, 6, 7};
Console.Write("Given Array\n");
printArray(arr);
MergeSort ob = new MergeSort();
ob.sort(arr, 0, arr.Length - 1);
Console.Write("\nSorted array\n");
printArray(arr);
}
}
// This code is contributed by ChitraNayal.
Output:
Given array is
12 11 13 5 6 7
Sorted array is
5 6 7 11 12 13
Time Complexity: Sorting arrays on different machines. Merge Sort is a recursive algo-
rithm and time complexity can be expressed as following recurrence relation.
T(n) = 2T(n/2) +
The above recurrence can be solved either using Recurrence Tree method or Master method.
403
Chapter 54. Merge Sort
1. Merge Sort is useful for sorting linked lists in O(nLogn) time.In case of linked lists the
case is different mainly due to difference in memory allocation of arrays and linked
lists. Unlike arrays, linked list nodes may not be adjacent in memory. Unlike array,
in linked list, we can insert items in the middle in O(1) extra space and O(1) time.
Therefore merge operation of merge sort can be implemented without extra space for
linked lists.
In arrays, we can do random access as elements are continuous in memory. Let us say
we have an integer (4-byte) array A and let the address of A[0] be x then to access
A[i], we can directly access the memory at (x + i*4). Unlike arrays, we can not do
random access in linked list. Quick Sort requires a lot of this kind of access. In linked
list to access i’th index, we have to travel each and every node from the head to i’th
node as we don’t have continuous block of memory. Therefore, the overhead increases
for quick sort. Merge sort accesses data sequentially and the need of random access is
low.
2. Inversion Count Problem
3. Used in External Sorting
Snapshots:
404
Chapter 54. Merge Sort
405
Chapter 54. Merge Sort
Improved By : ChitraNayal
Source
https://www.geeksforgeeks.org/merge-sort/
406
Chapter 55
Merge Sort with O(1) extra space merge and O(n lg n) time - GeeksforGeeks
We have discussed Merge sort. How to modify the algorithm so that merge works in O(1)
extra space and algorithm still works in O(n Log n) time. We may assume that the input
values are integers only.
Examples:
Input : 5 4 3 2 1
Output : 1 2 3 4 5
For integer types, merge sort can be made inplace using some mathematics trick of modulus
and division. That means storing two elements value at one index and can be extracted
using modulus and division.
First we have to find a value greater than all the elements of the array. Now we can store
the original value as modulus and the second value as division. Suppose we want to store
arr[i] and arr[j] both at index i(means in arr[i]). First we have to find a ‘maxval’ greater
than both arr[i] and arr[j]. Now we can store as arr[i] = arr[i] + arr[j]*maxval. Now
arr[i]%maxval will give the original value of arr[i] and arr[i]/maxval will give the value
of arr[j]. So below is the implementation on merge sort.
C++
407
Chapter 55. Merge Sort with O(1) extra space merge and O(n lg n) time
408
Chapter 55. Merge Sort with O(1) extra space merge and O(n lg n) time
{
int maxele = *max_element(arr, arr+n) + 1;
mergeSortRec(arr, 0, n-1, maxele);
}
int main()
{
int arr[] = { 999, 612, 589, 856, 56, 945, 243 };
int n = sizeof(arr) / sizeof(arr[0]);
mergeSort(arr, n);
cout << "Sorted array \n";
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
C#
409
Chapter 55. Merge Sort with O(1) extra space merge and O(n lg n) time
arr[k] = arr[k] +
(arr[j] % maxele) *
maxele;
k++;
j++;
}
}
while (i <= mid)
{
arr[k] = arr[k] + (arr[i] %
maxele) * maxele;
k++;
i++;
}
while (j <= end)
{
arr[k] = arr[k] + (arr[j] %
maxele) * maxele;
k++;
j++;
}
// Obtaining actual values
for ( i = beg; i <= end; i++)
arr[i] = arr[i] / maxele;
}
// Recursive merge sort
// with extra parameter, naxele
static void mergeSortRec(int []arr, int beg,
int end, int maxele)
{
if (beg < end)
{
int mid = (beg + end) / 2;
mergeSortRec(arr, beg,
mid, maxele);
mergeSortRec(arr, mid + 1,
end, maxele);
merge(arr, beg, mid,
end, maxele);
}
}
// This functions finds
// max element and calls
// recursive merge sort.
static void mergeSort(int []arr, int n)
410
Chapter 55. Merge Sort with O(1) extra space merge and O(n lg n) time
{
int maxele = arr.Max() + 1;
mergeSortRec(arr, 0, n - 1, maxele);
}
//Driver code
public static void Main ()
{
int []arr = {999, 612, 589,
856, 56, 945, 243};
int n = arr.Length;
mergeSort(arr, n);
Console.WriteLine("Sorted array ");
for (int i = 0; i < n; i++)
Console.Write( arr[i] + " ");
}
}
// This code is contributed
// by inder_verma.
Output:
Sorted array
56 243 589 612 856 945 999
Improved By : inderDuMCA
Source
https://www.geeksforgeeks.org/merge-sort-with-o1-extra-space-merge-and-on-lg-n-time/
411
Chapter 56
Minimum difference between adjacent elements of array which contain elements from each
row of a matrix - GeeksforGeeks
Given a matrix of N rows and M columns, the task is to find the minimum absolute
difference between any of the two adjacent elements of an array of size N, which is created
by picking one element from each row of the matrix. Note the element picked from row 1
will become arr[0], element picked from row 2 will become arr[1] and so on.
Examples:
Input : N = 2, M = 2
m[2][2] = { 8, 2,
6, 8 }
Output : 0.
Picking 8 from row 1 and picking 8 from row 2, we create an array { 8, 8 } and minimum
difference between any of adjacent element is 0.
Input : N = 3, M = 3
m[3][3] = { 1, 2, 3
4, 5, 6
7, 8, 9 }
Output : 1.
The idea is to sort all rows individually and then do binary search to find the closest element
in next row for each element.
412
Chapter 56. Minimum difference between adjacent elements of array which contain
elements from each row of a matrix
To do this in an efficient manner, sort each row of the matrix. Starting from row 1 to row N
– 1 of matrix, for each element m[i][j] of current row in the matrix, find the smallest element
in the next row which is greater than or equal to the current element, say p and the largest
element which is smaller than the current element, say q. This can be done using Binary
Search. Finally,find the minimum of the difference of current element from p and q and
update the variable.
Below is implementation of this approach:
C/C++
413
Chapter 56. Minimum difference between adjacent elements of array which contain
elements from each row of a matrix
{
for (int j = 0; j < m; j++)
{
// Search smallest element in the next row which
// is greater than or equal to the current element
int p = bsearch(0, m-1, arr[i][j], arr[i + 1]);
ans = min(ans, abs(arr[i + 1][p] - arr[i][j]));
// largest element which is smaller than the current
// element in the next row must be just before
// smallest element which is greater than or equal
// to the current element because rows are sorted.
if (p-1 >= 0)
ans = min(ans, abs(arr[i + 1][p - 1] - arr[i][j]));
}
}
return ans;
}
// Driven Program
int main()
{
int m[R][C] =
{
8, 5,
6, 8,
};
cout << mindiff(m, R, C) << endl;
return 0;
}
Java
414
Chapter 56. Minimum difference between adjacent elements of array which contain
elements from each row of a matrix
{
int mid = (low + high)/2;
if(low <= high)
{
if(arr[mid] < n)
return bsearch(mid +1, high, n, arr);
return bsearch(low, mid - 1, n, arr);
}
return low;
}
// Return the minimum absolute difference adjacent
// elements of array
static int mindiff(int arr[][], int n, int m)
{
// Sort each row of the matrix.
for (int i = 0; i < n; i++)
Arrays.sort(arr[i]);
int ans = +2147483647;
// For each matrix element
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < m; j++)
{
// Search smallest element in the
// next row which is greater than
// or equal to the current element
int p = bsearch(0, m-1, arr[i][j], arr[i + 1]);
ans = Math.min(ans, Math.abs(arr[i + 1][p] - arr[i][j]));
// largest element which is smaller than the current
// element in the next row must be just before
// smallest element which is greater than or equal
// to the current element because rows are sorted.
if (p-1 >= 0)
ans = Math.min(ans,
Math.abs(arr[i + 1][p - 1] - arr[i][j]));
}
}
return ans;
}
415
Chapter 56. Minimum difference between adjacent elements of array which contain
elements from each row of a matrix
//Driver code
public static void main (String[] args)
{
int m[][] ={{8, 5},
{6, 8}};
System.out.println(mindiff(m, R, C));
}
}
//This code is contributed by Anant Agarwal.
Python
416
Chapter 56. Minimum difference between adjacent elements of array which contain
elements from each row of a matrix
Output:
Source
https://www.geeksforgeeks.org/minimum-difference-adjacent-elements-array-contain-elements-row-matrix/
417
Chapter 57
Input: x = 2, y = 3, p = 5
Output: 3
Explanation: 2^3 % 5 = 8 % 5 = 3.
Input: x = 2, y = 5, p = 13
Output: 6
Explanation: 2^5 % 13 = 32 % 13 = 6.
418
Chapter 57. Modular Exponentiation (Power in Modular Arithmetic)
// n must be even now
y = y>>1; // y = y/2
x = x*x; // Change x to x^2
}
return res;
}
The problem with above solutions is, overflow may occur for large value of n or x. Therefore,
power is generally evaluated under modulo of a large number.
Below is the fundamental modular property that is used for efficiently computing power
under modular arithmetic.
(50 * 100) mod 13 = ( (50 mod 13) * (100 mod 13) ) mod 13
or (5000) mod 13 = ( 11 * 9 ) mod 13
or 8 = 8
419
Chapter 57. Modular Exponentiation (Power in Modular Arithmetic)
Java
420
Chapter 57. Modular Exponentiation (Power in Modular Arithmetic)
return res;
}
// Driver Program to test above functions
public static void main(String args[])
{
int x = 2;
int y = 5;
int p = 13;
System.out.println("Power is " + power(x, y, p));
}
}
// This code is contributed by Nikita Tiwari.
Python3
421
Chapter 57. Modular Exponentiation (Power in Modular Arithmetic)
# This code is contributed by Nikita Tiwari.
C#
422
Chapter 57. Modular Exponentiation (Power in Modular Arithmetic)
PHP
<?php
// Iterative PHP program to
// compute modular power
// Iterative Function to
// calculate (x^y)%p in O(log y)
function power($x, $y, $p)
{
// Initialize result
$res = 1;
// Update x if it is more
// than or equal to p
$x = $x % $p;
while ($y > 0)
{
// If y is odd, multiply
// x with result
if ($y & 1)
$res = ($res * $x) % $p;
// y must be even now
// y = $y/2
$y = $y >> 1;
$x = ($x * $x) % $p;
}
return $res;
}
// Driver Code
$x = 2;
$y = 5;
$p = 13;
echo "Power is ", power($x, $y, $p);
// This code is contributed by aj_36
?>
Output :
Power is 6
423
Chapter 57. Modular Exponentiation (Power in Modular Arithmetic)
This article is contributed by Shivam Agrawal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : jit_t, rd10, Mithun Kumar
Source
https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/
424
Chapter 58
Modular exponentiation
(Recursive)
Input : a = -3 b = 5 c = 89
Output : 24
425
Chapter 58. Modular exponentiation (Recursive)
Note:
Also as the product of (a ^ b/2) * (a ^ b/2) and a * (a ^( b-1) may cause overflow, hence
we must be careful about those scenarios
Java
426
Chapter 58. Modular exponentiation (Recursive)
class GFG
{
static int exponentMod(int A,
int B, int C)
{
// Base cases
if (A == 0)
return 0;
if (B == 0)
return 1;
// If B is even
long y;
if (B % 2 == 0)
{
y = exponentMod(A, B / 2, C);
y = (y * y) % C;
}
// If B is odd
else
{
y = A % C;
y = (y * exponentMod(A, B - 1,
C) % C) % C;
}
return (int)((y + C) % C);
}
// Driver Code
public static void main(String args[])
{
int A = 2, B = 5, C = 13;
System.out.println("Power is " +
exponentMod(A, B, C));
}
}
// This code is contributed
// by Swetank Modi.
Python3
427
Chapter 58. Modular exponentiation (Recursive)
# Base Cases
if (A == 0):
return 0
if (B == 0):
return 1
# If B is Even
y = 0
if (B % 2 == 0):
y = exponentMod(A, B / 2, C)
y = (y * y) % C
# If B is Odd
else:
y = A % C
y = (y * exponentMod(A, B - 1,
C) % C) % C
return ((y + C) % C)
# Driver Code
A = 2
B = 5
C = 13
print("Power is", exponentMod(A, B, C))
# This code is contributed
# by Swetank Modi.
C#
// Recursive C# program
// to compute modular power
class GFG
{
static int exponentMod(int A, int B, int C)
{
// Base cases
if (A == 0)
return 0;
if (B == 0)
return 1;
// If B is even
long y;
if (B % 2 == 0)
{
428
Chapter 58. Modular exponentiation (Recursive)
PHP
<?php
// Recursive PHP program to
// compute modular power
function exponentMod($A, $B, $C)
{
// Base cases
if ($A == 0)
return 0;
if ($B == 0)
return 1;
// If B is even
if ($B % 2 == 0)
{
$y = exponentMod($A, $B / 2, $C);
$y = ($y * $y) % $C;
}
// If B is odd
429
Chapter 58. Modular exponentiation (Recursive)
else
{
$y = $A % $C;
$y = ($y * exponentMod($A, $B - 1,
$C) % $C) % $C;
}
return (($y + $C) % $C);
}
// Driver Code
$A = 2;
$B = 5;
$C = 13;
echo "Power is " . exponentMod($A, $B, $C);
// This code is contributed
// by Swetank Modi.
?>
Output:
Power is 6
Source
https://www.geeksforgeeks.org/modular-exponentiation-recursive/
430
Chapter 59
A simple solution is to one by one consider every term of first polynomial and multiply it
with every term of second polynomial. Following is algorithm of this simple method.
multiply(A[0..m-1], B[0..n01])
1) Create a product array prod[] of size m+n-1.
2) Initialize all entries in prod[] as 0.
3) Travers array A[] and do following for every element A[i]
...(3.a) Traverse array B[] and do following for every element B[j]
prod[i+j] = prod[i+j] + A[i] * B[j]
4) Return prod[].
431
Chapter 59. Multiply two polynomials
#include <iostream>
using namespace std;
// A[] represents coefficients of first polynomial
// B[] represents coefficients of second polynomial
// m and n are sizes of A[] and B[] respectively
int *multiply(int A[], int B[], int m, int n)
{
int *prod = new int[m+n-1];
// Initialize the porduct polynomial
for (int i = 0; i<m+n-1; i++)
prod[i] = 0;
// Multiply two polynomials term by term
// Take ever term of first polynomial
for (int i=0; i<m; i++)
{
// Multiply the current term of first polynomial
// with every term of second polynomial.
for (int j=0; j<n; j++)
prod[i+j] += A[i]*B[j];
}
return prod;
}
// A utility function to print a polynomial
void printPoly(int poly[], int n)
{
for (int i=0; i<n; i++)
{
cout << poly[i];
if (i != 0)
cout << "x^" << i ;
if (i != n-1)
cout << " + ";
}
}
// Driver program to test above functions
int main()
{
// The following array represents polynomial 5 + 10x^2 + 6x^3
int A[] = {5, 0, 10, 6};
// The following array represents polynomial 1 + 2x + 4x^2
432
Chapter 59. Multiply two polynomials
Output
First polynomial is
5 + 0x^1 + 10x^2 + 6x^3
Second polynomial is
1 + 2x^1 + 4x^2
Product polynomial is
5 + 10x^1 + 30x^2 + 26x^3 + 52x^4 + 24x^5
Time complexity of the above solution is O(mn). If size of two polynomials same, then time
complexity is O(n2 ).
Can we do better?
There are methods to do multiplication faster than O(n2 ) time. These methods are mainly
based on divide and conquer. Following is one simple method that divides the given polyno-
mial (of degree n) into two polynomials one containing lower degree terms(lower than n/2)
and other containing higher degree terns (higher than or equal to n/2)
433
Chapter 59. Multiply two polynomials
So the above divide and conquer approach requires 4 multiplications and O(n) time to add
all 4 results. Therefore the time complexity is T(n) = 4T(n/2) + O(n). The solution of the
recurrence is O(n2 ) which is same as the above simple solution.
The idea is to reduce number of multiplications to 3 and make the recurrence as T(n) =
3T(n/2) + O(n)
How to reduce number of multiplications?
This requires a little trick similar toStrassen’s Matrix Multiplication. We do following 3
multiplications.
In Depth Explanation
Conventional polynomial multiplication uses 4 coefficient multiplications:
(a + b)(c + d) = ad + bc + ac + bd
The rest of the two components are exactly the middle coefficient for product of two poly-
nomials. Therefore, the product can be computed as:
434
Chapter 59. Multiply two polynomials
Sources:
http://www.cse.ust.hk/~dekai/271/notes/L03/L03.pdf
This article is contributed by Harsh. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above.
Improved By : Mr.L
Source
https://www.geeksforgeeks.org/multiply-two-polynomials-2/
435
Chapter 60
Input : Capacity = 5
l = 2
Output : 4
At the start of 1st day, water in tank = 5
and at the end of the 1st day = (5 - 1) = 4
At the start of 2nd day, water in tank = 4 + 2 = 6
but tank capacity is 5 so water = 5
and at the end of the 2nd day = (5 - 2) = 3
At the start of 3rd day, water in tank = 3 + 2 = 5
and at the end of the 3rd day = (5 - 3) = 2
At the start of 4th day, water in tank = 2 + 2 = 4
and at the end of the 4th day = (4 - 4) = 0
So final answer will be 4
We can see that tank will be full for starting (l + 1) days because water taken out is less
than water being filled. After that, each day water in the tank will be decreased by 1 more
liter and on (l + 1 + i)th day (C – (i)(i + 1) / 2) liter water will remain before taking
drinking water.
Now we need to find a minimal day (l + 1 + K), in which even after filling the tank by l
liters we have water less than l in tank i.e. on (l + 1 + K – 1)th day tank becomes empty
436
Chapter 60. Number of days after which tank will become empty
437
Chapter 60. Number of days after which tank will become empty
Java
438
Chapter 60. Number of days after which tank will become empty
hi = mid;
// if (C - l) is more then search on
// right side
else
lo = mid + 1;
}
// final answer will be obtained by adding
// l to binary search result
return (l + lo);
}
// Driver code to test above methods
public static void main(String args[])
{
int C = 5;
int l = 2;
System.out.println(minDaysToEmpty(C, l));
}
}
// This code is contributed by Sumit Ghosh
Python3
439
Chapter 60. Number of days after which tank will become empty
C#
440
Chapter 60. Number of days after which tank will become empty
441
Chapter 60. Number of days after which tank will become empty
Output:
Alternate Solution :
It can be solved mathematically with a simple formula:
Let’s Assume C>L. Let d be the amount of days after the Lth when the tank become
empty.During that time, there will be (d-1)refills and d withdrawals.
Hence we need to solve this equation :
C++
442
Chapter 60. Number of days after which tank will become empty
return std::ceil(eq_root) + l;
}
// Driver code to test above methods
int main()
{
cout << minDaysToEmpty(5, 2) << endl;
cout << minDaysToEmpty(6514683, 4965) << endl;
return 0;
}
Java
Python3
443
Chapter 60. Number of days after which tank will become empty
C#
PHP
444
Chapter 60. Number of days after which tank will become empty
<?php
// PHP code to find number
// of days after which
// tank will become empty
// Method returns minimum
// number of days after
// which tank will become empty
function minDaysToEmpty($C, $l)
{
if ($l >= $C)
return $C;
$eq_root = (int)sqrt(1 + 8 *
($C - $l) - 1) / 2;
return ceil($eq_root) + $l;
}
// Driver code
echo minDaysToEmpty(5, 2), "\n";
echo minDaysToEmpty(6514683,
4965), "\n";
// This code is contributed
// by akt_mit
?>
Output :
4
8573
Source
https://www.geeksforgeeks.org/number-days-tank-will-become-empty/
445
Chapter 61
Number of ways to divide a given number as a set of integers in decreasing order - Geeks-
forGeeks
Given two numbers and . The task is to find the number of ways in which a can be rep-
Input : a = 4, m = 4
Output : 2 –> ({4}, {3, 1})
Note: {2, 2} is not a valid set as values are not in decreasing order
Input : a = 7, m = 5
Output : 5 –> ({7}, {6, 1}, {5, 2}, {4, 3}, {4, 2, 1})
Approach: This problem can be solved by Divide and Conquer using a recursive approach
which follows the following conditions:
446
Chapter 61. Number of ways to divide a given number as a set of integers in decreasing
order
447
Chapter 61. Number of ways to divide a given number as a set of integers in decreasing
order
numWays[(a,m,prev)] += countNumOfWays(a-i,m-1,i)
return numWays[(a, m, prev)]
# Values of 'a' and 'm' for which
# solution is to be found
# MAX_CONST is extremely large value
# used for first comparison in the function
a, m, MAX_CONST = 7, 5, 10**5
print(countNumOfWays(a, m, MAX_CONST))
Output:
Source
https://www.geeksforgeeks.org/number-of-ways-to-divide-a-given-number-as-a-set-of-integers-in-decreasing-order/
448
Chapter 62
Input : n = 1
Output : 5 6 7 8 9
Explanation: Here, 5! = 120, 6! = 720,
7! = 5040, 8! = 40320 and 9! = 362880.
Input : n = 2
Output : 10 11 12 13 14
449
Chapter 62. Numbers whose factorials end with n zeros
450
Chapter 62. Numbers whose factorials end with n zeros
Java
451
Chapter 62. Numbers whose factorials end with n zeros
k++;
low++;
}
// Print result
for (int i = 0; i < k; i++)
System.out.print(result[i] + " ");
}
// Driver code
public static void main(String args[])
{
int n = 3;
binarySearch(n);
}
}
// This code is contributed
// by Nikita Tiwari.
Python3
452
Chapter 62. Numbers whose factorials end with n zeros
C#
453
Chapter 62. Numbers whose factorials end with n zeros
Output:
10 11 12 13 14
Source
https://www.geeksforgeeks.org/numbers-whose-factorials-end-with-n-zeros/
454
Chapter 63
A Naive Solution is to consider all subsets of size 3 and find minimum distance for every
subset. Finally return the largest of all minimum distances.
An Efficient Solution is based on Binary Search. We first sort the array. Now we know
maximum possible value result is arr[n-1] – arr[0] (for k = 2). We do binary search for
maximum result for given k. We start with middle of maximum possible result. If middle
455
Chapter 63. Place k elements such that minimum distance is maximized
is a feasible solution, we search on right half of mid. Else we search is left half. To check
feasibility, we place k elements under given mid distance.
C++
456
Chapter 63. Place k elements such that minimum distance is maximized
sort(arr,arr+n);
// Initialize result.
int res = -1;
// Consider the maximum possible distance
int left = 0, right = arr[n-1];
// Do binary search for largest minimum distance
while (left < right)
{
int mid = (left + right)/2;
// If it is possible to place k elements
// with minimum distance mid, search for
// higher distance.
if (isFeasible(mid, arr, n, k))
{
// Change value of variable max to mid iff
// all elements can be successfully placed
res = max(res, mid);
left = mid + 1;
}
// If not possible to place k elements, search
// for lower distance
else
right = mid;
}
return res;
}
// Driver code
int main()
{
int arr[] = {1, 2, 8, 4, 9};
int n = sizeof(arr)/sizeof(arr[0]);
int k = 3;
cout << largestMinDist(arr, n, k);
return 0;
}
Java
457
Chapter 63. Place k elements such that minimum distance is maximized
class GFG
{
// Returns true if it is possible to
// arrange k elements of arr[0..n-1]
// with minimum distance given as mid.
static boolean isFeasible(int mid, int arr[],
int n, int k)
{
// Place first element at arr[0] position
int pos = arr[0];
// Initialize count of elements placed.
int elements = 1;
// Try placing k elements with minimum
// distance mid.
for (int i=1; i<n; i++)
{
if (arr[i] - pos >= mid)
{
// Place next element if its
// distance from the previously
// placed element is greater
// than current mid
pos = arr[i];
elements++;
// Return if all elements are
// placed successfully
if (elements == k)
return true;
}
}
return false;
}
// Returns largest minimum distance for
// k elements in arr[0..n-1]. If elements
// can't be placed, returns -1.
static int largestMinDist(int arr[], int n,
int k)
{
// Sort the positions
Arrays.sort(arr);
// Initialize result.
int res = -1;
458
Chapter 63. Place k elements such that minimum distance is maximized
// Consider the maximum possible distance
int left = arr[0], right = arr[n-1];
// Do binary search for largest
// minimum distance
while (left < right)
{
int mid = (left + right)/2;
// If it is possible to place k
// elements with minimum distance mid,
// search for higher distance.
if (isFeasible(mid, arr, n, k))
{
// Change value of variable max to
// mid if all elements can be
// successfully placed
res = Math.max(res, mid);
left = mid + 1;
}
// If not possible to place k elements,
// search for lower distance
else
right = mid;
}
return res;
}
// driver code
public static void main (String[] args)
{
int arr[] = {1, 2, 8, 4, 9};
int n = arr.length;
int k = 3;
System.out.print(largestMinDist(arr, n, k));
}
}
// This code is contributed by Anant Agarwal.
C#
459
Chapter 63. Place k elements such that minimum distance is maximized
public class GFG {
// Returns true if it is possible to
// arrange k elements of arr[0..n-1]
// with minimum distance given as mid.
static bool isFeasible(int mid, int []arr,
int n, int k)
{
// Place first element at arr[0]
// position
int pos = arr[0];
// Initialize count of elements placed.
int elements = 1;
// Try placing k elements with minimum
// distance mid.
for (int i = 1; i < n; i++)
{
if (arr[i] - pos >= mid)
{
// Place next element if its
// distance from the previously
// placed element is greater
// than current mid
pos = arr[i];
elements++;
// Return if all elements are
// placed successfully
if (elements == k)
return true;
}
}
return false;
}
// Returns largest minimum distance for
// k elements in arr[0..n-1]. If elements
// can't be placed, returns -1.
static int largestMinDist(int []arr, int n,
int k)
{
460
Chapter 63. Place k elements such that minimum distance is maximized
461
Chapter 63. Place k elements such that minimum distance is maximized
}
// This code is contributed by Sam007.
PHP
<?php
// PHP program to find largest
// minimum distance among k points.
// Returns true if it is possible
// to arrange k elements of
// arr[0..n-1] with minimum
// distance given as mid.
function isFeasible($mid, $arr,
$n, $k)
{
// Place first element
// at arr[0] position
$pos = $arr[0];
// Initialize count of
// elements placed.
$elements = 1;
// Try placing k elements
// with minimum distance mid.
for ($i = 1; $i < $n; $i++)
{
if ($arr[$i] - $pos >= $mid)
{
// Place next element if
// its distance from the
// previously placed
// element is greater
// than current mid
$pos = $arr[$i];
$elements++;
// Return if all elements
// are placed successfully
if ($elements == $k)
return true;
}
}
return 0;
}
462
Chapter 63. Place k elements such that minimum distance is maximized
463
Chapter 63. Place k elements such that minimum distance is maximized
Output :
Source
https://www.geeksforgeeks.org/place-k-elements-such-that-minimum-distance-is-maximized/
464
Chapter 64
Examples:
Input : 2
Output : Disk 1 moved from A to B
465
Chapter 64. Program for Tower of Hanoi
Input : 3
Output : Disk 1 moved from A to C
Disk 2 moved from A to B
Disk 1 moved from C to B
Disk 3 moved from A to C
Disk 1 moved from B to A
Disk 2 moved from B to C
Disk 1 moved from A to C
C/C++
#include <stdio.h>
// C recursive function to solve tower of hanoi puzzle
void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod)
{
if (n == 1)
{
printf("\n Move disk 1 from rod %c to rod %c", from_rod, to_rod);
return;
}
towerOfHanoi(n-1, from_rod, aux_rod, to_rod);
printf("\n Move disk %d from rod %c to rod %c", n, from_rod, to_rod);
towerOfHanoi(n-1, aux_rod, to_rod, from_rod);
}
int main()
{
int n = 4; // Number of disks
towerOfHanoi(n, 'A', 'C', 'B'); // A, B and C are names of rods
return 0;
}
Java
466
Chapter 64. Program for Tower of Hanoi
System.out.println("Move disk 1 from rod " + from_rod + " to rod " + to_rod);
return;
}
towerOfHanoi(n-1, from_rod, aux_rod, to_rod);
System.out.println("Move disk " + n + " from rod " + from_rod + " to rod " + to_rod);
towerOfHanoi(n-1, aux_rod, to_rod, from_rod);
}
// Driver method
public static void main(String args[])
{
int n = 4; // Number of disks
towerOfHanoi(n, 'A', 'C', 'B'); // A, B and C are names of rods
}
}
Python
PHP
<?php
//PHP code to solve Tower of Hanoi problem.
// Recursive Function to solve Tower of Hanoi
function towerOfHanoi($n, $from_rod, $to_rod, $aux_rod) {
if ($n === 1) {
echo ("Move disk 1 from rod $from_rod to rod $to_rod \n");
return;
}
467
Chapter 64. Program for Tower of Hanoi
towerOfHanoi($n-1, $from_rod, $aux_rod, $to_rod);
echo ("Move disk $n from rod $from_rod to rod $to_rod \n");
towerOfHanoi($n-1, $aux_rod, $to_rod, $from_rod);
}
// Driver code
// number of disks
$n = 4;
// A, B and C are names of rods
towerOfHanoi($n, 'A', 'C', 'B');
// This code is contributed by akash7981
?>
C#
468
Chapter 64. Program for Tower of Hanoi
int n = 4;
// A, B and C are names of rods
towerOfHanoi(n, 'A', 'C', 'B');
}
}
// This code is contributed by Sam007
Output:
• Recursive Functions
• Iterative solution to TOH puzzle
• Quiz on Recursion
References:
http://en.wikipedia.org/wiki/Tower_of_Hanoi
Improved By : vaibhav29498, Rustam Ali
Source
https://www.geeksforgeeks.org/c-program-for-tower-of-hanoi/
469
Chapter 65
0, 1, 2, 3
0 - 0, 1, 1, 2 -------- GROUP_A(0)
4 - 1, 2, 2, 3 -------- GROUP_A(1)
8 - 1, 2, 2, 3 -------- GROUP_A(1)
12 - 2, 3, 3, 4 -------- GROUP_A(2)
470
Chapter 65. Program to count number of set bits in an (big) array
16 - 1, 2, 2, 3 -------- GROUP_A(1)
20 - 2, 3, 3, 4 -------- GROUP_A(2)
24 - 2, 3, 3, 4 -------- GROUP_A(2)
28 - 3, 4, 4, 5 -------- GROUP_A(3) ... so on
From the table, there is a patten emerging in multiples of 4, both in the table as well as in
the group parameter. The sequence can be generalized as shown in the code.
Complexity:
All the operations takes O(1) except iterating over the array. The time complexity is O(n)
where ‘n’ is size of array. Space complexity depends on the meta program that generates
look up.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* Size of array 64 K */
#define SIZE (1 << 16)
/* Meta program that generates set bit count
array of first 256 integers */
/* GROUP_A - When combined with META_LOOK_UP
generates count for 4x4 elements */
#define GROUP_A(x) x, x + 1, x + 1, x + 2
/* GROUP_B - When combined with META_LOOK_UP
generates count for 4x4x4 elements */
#define GROUP_B(x) GROUP_A(x), GROUP_A(x+1), GROUP_A(x+1), GROUP_A(x+2)
/* GROUP_C - When combined with META_LOOK_UP
generates count for 4x4x4x4 elements */
#define GROUP_C(x) GROUP_B(x), GROUP_B(x+1), GROUP_B(x+1), GROUP_B(x+2)
/* Provide appropriate letter to generate the table */
#define META_LOOK_UP(PARAMETER) \
GROUP_##PARAMETER(0), \
GROUP_##PARAMETER(1), \
GROUP_##PARAMETER(1), \
GROUP_##PARAMETER(2) \
471
Chapter 65. Program to count number of set bits in an (big) array
472
Chapter 65. Program to count number of set bits in an (big) array
Contributed by Venki. Please write comments if you find anything incorrect, or you want
to share more information about the topic discussed above.
Source
https://www.geeksforgeeks.org/program-to-count-number-of-set-bits-in-an-big-array/
473
Chapter 66
• The array of elements is divided into parts repeatedly until it is not possible to divide
it further.
• It is also known as “partition exchange sort”.
• It uses a key element (pivot) for partitioning the elements.
• One left partition contains all those elements that are smaller than the pivot and one
right partition contains all those elements which are greater than the key element.
474
Chapter 66. Quick Sort vs Merge Sort
Merge sort is an external algorithm and based on divide and conquer strategy. In this:
• The elements are split into two sub-arrays (n/2) again and again until only one element
is left.
• Merge sort uses additional storage for sorting the auxiliary array.
• Merge sort uses three arrays where two are used for storing each half, and the third
external one is used to store the final sorted list by merging other two and each array
is then sorted recursively.
• At last, the all sub arrays are merged to make it ‘n’ element size of the array.
475
Chapter 66. Quick Sort vs Merge Sort
476
Chapter 66. Quick Sort vs Merge Sort
Source
https://www.geeksforgeeks.org/quick-sort-vs-merge-sort/
477
Chapter 67
QuickSort
QuickSort - GeeksforGeeks
Like Merge Sort, QuickSort is a Divide and Conquer algorithm. It picks an element as pivot
and partitions the given array around the picked pivot. There are many different versions
of quickSort that pick pivot in different ways.
The key process in quickSort is partition(). Target of partitions is, given an array and an
element x of array as pivot, put x at its correct position in sorted array and put all smaller
elements (smaller than x) before x, and put all greater elements (greater than x) after x.
All this should be done in linear time.
Pseudo Code for recursive QuickSort function :
478
Chapter 67. QuickSort
Partition Algorithm
There can be many ways to do partition, following pseudo code adopts the method given
in CLRS book. The logic is simple, we start from the leftmost element and keep track of
index of smaller (or equal to) elements as i. While traversing, if we find a smaller element,
we swap current element with arr[i]. Otherwise we ignore current element.
479
Chapter 67. QuickSort
Illustration of partition() :
480
Chapter 67. QuickSort
i = 2
arr[] = {10, 30, 40, 90, 80, 50, 70} // 80 and 40 Swapped
j = 5 : Since arr[j] <= pivot, do i++ and swap arr[i] with arr[j]
i = 3
arr[] = {10, 30, 40, 50, 80, 90, 70} // 90 and 50 Swapped
Implementation:
Following are C++, Java and Python implementations of QuickSort.
C/C++
/* C implementation QuickSort */
#include<stdio.h>
// A utility function to swap two elements
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition (int arr[], int low, int high)
{
int pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high- 1; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++; // increment index of smaller element
481
Chapter 67. QuickSort
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("n");
}
// Driver program to test above functions
int main()
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr)/sizeof(arr[0]);
quickSort(arr, 0, n-1);
printf("Sorted array: n");
printArray(arr, n);
return 0;
}
Java
482
Chapter 67. QuickSort
483
Chapter 67. QuickSort
// Recursively sort elements before
// partition and after partition
sort(arr, low, pi-1);
sort(arr, pi+1, high);
}
}
/* A utility function to print array of size n */
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
// Driver program
public static void main(String args[])
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = arr.length;
QuickSort ob = new QuickSort();
ob.sort(arr, 0, n-1);
System.out.println("sorted array");
printArray(arr);
}
}
/*This code is contributed by Rajat Mishra */
Python
484
Chapter 67. QuickSort
C#
485
Chapter 67. QuickSort
486
Chapter 67. QuickSort
Output:
Sorted array:
1 5 7 8 9 10
Analysis of QuickSort
Time taken by QuickSort in general can be written as following.
The first two terms are for two recursive calls, the last term is for the partition process. k
is the number of elements which are smaller than pivot.
The time taken by QuickSort depends upon the input array and partition strategy. Following
are three cases.
Worst Case: The worst case occurs when the partition process always picks greatest or
smallest element as pivot. If we consider above partition strategy where last element is
always picked as pivot, the worst case would occur when the array is already sorted in
increasing or decreasing order. Following is recurrence for worst case.
487
Chapter 67. QuickSort
The solution of above recurrence is (nLogn). It can be solved using case 2 of Master
Theorem.
Average Case:
To do average case analysis, we need to consider all possible permutation of array and
calculate time taken by every permutation which doesn’t look easy.
We can get an idea of average case by considering the case when partition puts O(n/9)
elements in one set and O(9n/10) elements in other set. Following is recurrence for this
case.
488
Chapter 67. QuickSort
Snapshots:
489
Chapter 67. QuickSort
490
Chapter 67. QuickSort
• Quiz on QuickSort
• Recent Articles on QuickSort
• Coding practice for sorting.
491
Chapter 67. QuickSort
References:
http://en.wikipedia.org/wiki/Quicksort
Other Sorting Algorithms on GeeksforGeeks/GeeksQuiz:
Selection Sort, Bubble Sort, Insertion Sort, Merge Sort, Heap Sort, QuickSort, Radix Sort,
Counting Sort, Bucket Sort, ShellSort, Comb Sort, Pigeonhole Sort
Improved By : Palak Jain 5
Source
https://www.geeksforgeeks.org/quick-sort/
492
Chapter 68
Input is an array of points specified by their x and y coordinates. Output is a convex hull
of this set of points in ascending order of x coordinates.
Example :
Input : points[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4},
{0, 0}, {1, 2}, {3, 1}, {3, 3}};
Output : The points in convex hull are:
(0, 0) (0, 3) (3, 1) (4, 4)
Input : points[] = {(0, 0), (0, 4), (-4, 0), (5, 0),
(0, -6), (1, 0)};
Output : (-4, 0), (5, 0), (0, -6), (0, 4)
493
Chapter 68. Quickhull Algorithm for Convex Hull
1. Find the point with minimum x-coordinate lets say, min_x and similarly the point
with maximum x-coordinate, max_x.
2. Make a line joining these two points, say L. This line will divide the the whole set into
two parts. Take both the parts one by one and proceed further.
3. For a part, find the point P with maximum distance from the line L. P forms a triangle
with the points min_x, max_x. It is clear that the points residing inside this triangle
can never be the part of convex hull.
4. The above step divides the problem into two sub-problems (solved recursively). Now
the line joining the points P and min_x and the line joining the points P and max_x
are new lines and the points residing outside the triangle is the set of points. Repeat
point no. 3 till there no point left with the line. Add the end points of this point to
the convex hull.
Below is C++ implementation of above idea. The implementation uses set to store points
so that points can be printed in sorted order. A point is represented as a pair.
494
Chapter 68. Quickhull Algorithm for Convex Hull
// Returns the square of distance between
// p1 and p2.
int dist(iPair p, iPair q)
{
return (p.second - q.second) * (p.second - q.second) +
(p.first - q.first) * (p.first - q.first);
}
// returns a value proportional to the distance
// between the point p and the line joining the
// points p1 and p2
int lineDist(iPair p1, iPair p2, iPair p)
{
return abs ((p.second - p1.second) * (p2.first - p1.first) -
(p2.second - p1.second) * (p.first - p1.first));
}
// End points of line L are p1 and p2. side can have value
// 1 or -1 specifying each of the parts made by the line L
void quickHull(iPair a[], int n, iPair p1, iPair p2, int side)
{
int ind = -1;
int max_dist = 0;
// finding the point with maximum distance
// from L and also on the specified side of L.
for (int i=0; i<n; i++)
{
int temp = lineDist(p1, p2, a[i]);
if (findSide(p1, p2, a[i]) == side && temp > max_dist)
{
ind = i;
max_dist = temp;
}
}
// If no point is found, add the end points
// of L to the convex hull.
if (ind == -1)
{
hull.insert(p1);
hull.insert(p2);
return;
}
// Recur for the two parts divided by a[ind]
quickHull(a, n, a[ind], p1, -findSide(a[ind], p1, p2));
495
Chapter 68. Quickhull Algorithm for Convex Hull
496
Chapter 68. Quickhull Algorithm for Convex Hull
printHull(a, n);
return 0;
}
Input :
Time Complexity: The analysis is similar to Quick Sort. On average, we get time com-
plexity as O(n Log n), but in worst case, it can become O(n2 )
Source
https://www.geeksforgeeks.org/quickhull-algorithm-convex-hull/
497
Chapter 69
498
Chapter 69. Randomized Binary Search Algorithm
499
Chapter 69. Randomized Binary Search Algorithm
Output:
500
Chapter 69. Randomized Binary Search Algorithm
501
Chapter 69. Randomized Binary Search Algorithm
Output:
Source
https://www.geeksforgeeks.org/randomized-binary-search-algorithm/
502
Chapter 70
Please note that this problem is different from Search in a row wise and column wise sorted
matrix. Here matrix is more strictly sorted as first element of a row is greater than last
element of previous row.
A Simple Solution is to one by one compare x with every element of matrix. If matches,
then return position. If we reach end, return -1. Time complexity of this solution is O(n x
m).
An efficient solution is to typecast given 2D array to 1D array, then apply binary search
on the typecasted array.
503
Chapter 70. Search element in a sorted matrix
Example:
Consider: | 1 2 3 4|
x = 3, mat = | 5 6 7 8| Middle column:
| 9 10 11 12| = {2, 6, 10, 14}
|13 14 15 16| perform binary search on them
since, x < 6, discard the
last 2 rows as 'a' will
not lie in them(sorted matrix)
Now, only two rows are left
| 1 2 3 4|
x = 3, mat = | 5 6 7 8| Check whether element is present
on the middle elements of these
rows = {2, 6}
x != 2 or 6
If not, consider the four sub-parts
1st half of 1st row = {1}, 2nd half of 1st row = {3, 4}
1st half of 2nd row = {5}, 2nd half of 2nd row = {7, 8}
C++
504
Chapter 70. Search element in a sorted matrix
505
Chapter 70. Search element in a sorted matrix
// Do binary search in middle column.
// Condition to terminate the loop when the
// 2 desired rows are found
int i_low = 0;
int i_high = n-1;
int j_mid = m/2;
while ((i_low+1) < i_high)
{
int i_mid = (i_low + i_high) / 2;
// element found
if (mat[i_mid][j_mid] == x)
{
cout << "Found at (" << i_mid << ", "
<< j_mid << ")";
return;
}
else if (mat[i_mid][j_mid] > x)
i_high = i_mid;
else
i_low = i_mid;
}
// If element is present on the mid of the
// two rows
if (mat[i_low][j_mid] == x)
cout << "Found at (" << i_low << ","
<< j_mid << ")";
else if (mat[i_low+1][j_mid] == x)
cout << "Found at (" << (i_low+1)
<< ", " << j_mid << ")";
// Ssearch element on 1st half of 1st row
else if (x <= mat[i_low][j_mid-1])
binarySearch(mat, i_low, 0, j_mid-1, x);
// Search element on 2nd half of 1st row
else if (x >= mat[i_low][j_mid+1] &&
x <= mat[i_low][m-1])
binarySearch(mat, i_low, j_mid+1, m-1, x);
// Search element on 1st half of 2nd row
else if (x <= mat[i_low+1][j_mid-1])
binarySearch(mat, i_low+1, 0, j_mid-1, x);
506
Chapter 70. Search element in a sorted matrix
Java
507
Chapter 70. Search element in a sorted matrix
else
j_low = j_mid + 1;
}
// element not found
System.out.println ( "Element no found");
}
// Function to perform binary search on the mid
// values of row to get the desired pair of rows
// where the element can be found
static void sortedMatrixSearch(int mat[][], int n,
int m, int x)
{
// Single row matrix
if (n == 1)
{
binarySearch(mat, 0, 0, m - 1, x);
return;
}
// Do binary search in middle column.
// Condition to terminate the loop when the
// 2 desired rows are found
int i_low = 0;
int i_high = n - 1;
int j_mid = m / 2;
while ((i_low + 1) < i_high)
{
int i_mid = (i_low + i_high) / 2;
// element found
if (mat[i_mid][j_mid] == x)
{
System.out.println ( "Found at (" + i_mid +", "
+ j_mid +")");
return;
}
else if (mat[i_mid][j_mid] > x)
i_high = i_mid;
else
i_low = i_mid;
}
// If element is present on
508
Chapter 70. Search element in a sorted matrix
C#
// C# implementation to search
// an element in a sorted matrix
using System;
509
Chapter 70. Search element in a sorted matrix
class GFG
{
// This function does Binary search for x in i-th
// row. It does the search from mat[i][j_low] to
// mat[i][j_high]
static void binarySearch(int [,]mat, int i, int j_low,
int j_high, int x)
{
while (j_low <= j_high)
{
int j_mid = (j_low + j_high) / 2;
// Element found
if (mat[i,j_mid] == x)
{
Console.Write ( "Found at (" + i +
", " + j_mid +")");
return;
}
else if (mat[i,j_mid] > x)
j_high = j_mid - 1;
else
j_low = j_mid + 1;
}
// element not found
Console.Write ( "Element no found");
}
// Function to perform binary search on the mid
// values of row to get the desired pair of rows
// where the element can be found
static void sortedMatrixSearch(int [,]mat, int n,
int m, int x)
{
// Single row matrix
if (n == 1)
{
binarySearch(mat, 0, 0, m - 1, x);
return;
}
// Do binary search in middle column.
// Condition to terminate the loop when the
// 2 desired rows are found
int i_low = 0;
510
Chapter 70. Search element in a sorted matrix
int i_high = n - 1;
int j_mid = m / 2;
while ((i_low + 1) < i_high)
{
int i_mid = (i_low + i_high) / 2;
// element found
if (mat[i_mid,j_mid] == x)
{
Console.Write ( "Found at (" + i_mid +
", " + j_mid +")");
return;
}
else if (mat[i_mid,j_mid] > x)
i_high = i_mid;
else
i_low = i_mid;
}
// If element is present on
// the mid of the two rows
if (mat[i_low,j_mid] == x)
Console.Write ( "Found at (" + i_low +
"," + j_mid +")");
else if (mat[i_low + 1,j_mid] == x)
Console.Write ( "Found at (" + (i_low
+ 1) + ", " + j_mid +")");
// Ssearch element on 1st half of 1st row
else if (x <= mat[i_low,j_mid - 1])
binarySearch(mat, i_low, 0, j_mid - 1, x);
// Search element on 2nd half of 1st row
else if (x >= mat[i_low,j_mid + 1] &&
x <= mat[i_low,m - 1])
binarySearch(mat, i_low, j_mid + 1, m - 1, x);
// Search element on 1st half of 2nd row
else if (x <= mat[i_low + 1,j_mid - 1])
binarySearch(mat, i_low + 1, 0, j_mid - 1, x);
// search element on 2nd half of 2nd row
else
binarySearch(mat, i_low + 1, j_mid + 1, m - 1, x);
}
511
Chapter 70. Search element in a sorted matrix
// Driver program
public static void Main (String[] args)
{
int n = 4, m = 5, x = 8;
int [,]mat = {{0, 6, 8, 9, 11},
{20, 22, 28, 29, 31},
{36, 38, 50, 61, 63},
{64, 66, 100, 122, 128}};
sortedMatrixSearch(mat, n, m, x);
}
}
// This code is contributed by parashar...
Output:
Found at (0,2)
Time complexity: O(log n + log m). O(Log n) time is required to find the two desired rows.
Then O(Log m) time is required for binary search in one of the four parts with size equal
to m/2.
Improved By : parashar
Source
https://www.geeksforgeeks.org/search-element-sorted-matrix/
512
Chapter 71
In regular binary search algorithm evaluation and division perform as far as subarray size
is bigger than 0.
In our case if we want to keep single function we need to perform final evaluation in subarray
of size=2. Only in subarray size==2 is possible to check both EQUAL_OR_SMALLER
and EQUAL_OR_BIGGER conditions.
In below code, SC stands for Search Criteria.
513
Chapter 71. Search equal, bigger or smaller in a sorted array in Java
514
Chapter 71. Search equal, bigger or smaller in a sorted array in Java
515
Chapter 71. Search equal, bigger or smaller in a sorted array in Java
Output:
-1, EQUAL:-1
-1, EQUAL_OR_SMALLER:-1
-1, EQUAL_OR_BIGGER:0
0, EQUAL:0
0, EQUAL_OR_SMALLER:0
0, EQUAL_OR_BIGGER:0
1, EQUAL:-1
1, EQUAL_OR_SMALLER:0
1, EQUAL_OR_BIGGER:1
2, EQUAL:1
2, EQUAL_OR_SMALLER:1
2, EQUAL_OR_BIGGER:1
3, EQUAL:-1
3, EQUAL_OR_SMALLER:1
3, EQUAL_OR_BIGGER:2
4, EQUAL:2
4, EQUAL_OR_SMALLER:2
4, EQUAL_OR_BIGGER:2
5, EQUAL:-1
5, EQUAL_OR_SMALLER:2
5, EQUAL_OR_BIGGER:3
6, EQUAL:3
6, EQUAL_OR_SMALLER:3
6, EQUAL_OR_BIGGER:3
7, EQUAL:-1
7, EQUAL_OR_SMALLER:3
7, EQUAL_OR_BIGGER:-1
Source
https://www.geeksforgeeks.org/search-equal-bigger-or-smaller-in-a-sorted-array-in-java/
516
Chapter 72
Search in a Row-wise and Column-wise Sorted 2D Array using Divide and Conquer algorithm
- GeeksforGeeks
Given an n x n matrix, where every row and column is sorted in increasing order. Given a
key, how to decide whether this key is in the matrix.
A linear time complexity is discussed in the previous post. This problem can also be a very
good example for divide and conquer algorithms. Following is divide and conquer algorithm.
1) Find the middle element.
2) If middle element is same as key return.
3) If middle element is lesser than key then
….3a) search submatrix on lower side of middle element
….3b) Search submatrix on right hand side.of middle element
4) If middle element is greater than key then
….4a) search vertical submatrix on left side of middle element
….4b) search submatrix on right hand side.
517
Chapter 72. Search in a Row-wise and Column-wise Sorted 2D Array using Divide and
Conquer algorithm
518
Chapter 72. Search in a Row-wise and Column-wise Sorted 2D Array using Divide and
Conquer algorithm
519
Chapter 72. Search in a Row-wise and Column-wise Sorted 2D Array using Divide and
Conquer algorithm
Time complexity:
We are given a n*n matrix, the algorithm can be seen as recurring for 3 matrices of size n/2
x n/2. Following is recurrence for time complexity
Source
https://www.geeksforgeeks.org/search-in-a-row-wise-and-column-wise-sorted-2d-array-using-divide-and-conquer-al
520
Chapter 73
Sequences of given length where every element is more than or equal to twice of previous -
GeeksforGeeks
Given two integers m & n, find the number of possible sequences of length n such that each
of the next element is greater than or equal to twice of the previous element but less than
or equal to m.
Examples :
Input : m = 10, n = 4
Output : 4
There should be n elements and value of last
element should be at-most m.
The sequences are {1, 2, 4, 8}, {1, 2, 4, 9},
{1, 2, 4, 10}, {1, 2, 5, 10}
Input : m = 5, n = 2
Output : 6
The sequences are {1, 2}, {1, 3}, {1, 4},
{1, 5}, {2, 4}, {2, 5}
As per the given condition the n-th value of the sequence can be at most m. There can be
two cases for n-th element:
1. If it is m, then the (n-1)th element is at most m/2. We recur for m/2 and n-1.
2. If it is not m, then the n-1th element is at most is m-1. We recur for (m-1) and n.
521
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
The total number of sequences is the sum of the number of sequences including m and the
number of sequences where m is not included. Thus the original problem of finding number
of sequences of length n with max value m can be subdivided into independent subproblems
of finding number of sequences of length n with max value m-1 and number of sequences of
length n-1 with max value m/2.
C++
Java
522
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
C#
523
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
// If n is 0, found an empty special sequence
if(n == 0)
return 1;
// There can be two possibilities : (1) Reduce
// last element value (2) Consider last element
// as m and reduce number of terms
return getTotalNumberOfSequences (m-1, n) +
getTotalNumberOfSequences (m/2, n-1);
}
// Driver code
public static void Main ()
{
int m = 10;
int n = 4;
Console.Write("Total number of possible sequences " +
getTotalNumberOfSequences(m, n));
}
}
// This code is contributed by nitin mittal.
PHP
<?php
// PHP program to count total
// number of special sequences
// of length n where
// Recursive function to find
// the number of special sequences
function getTotalNumberOfSequences($m, $n)
{
// A special sequence cannot
// exist if length n is more
// than the maximum value m.
if ($m < $n)
return 0;
// If n is 0, found an empty
// special sequence
if ($n == 0)
return 1;
// There can be two possibilities :
524
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
Output:
Note that the above function computes the same sub problems again and again. Consider
the following tree for f(10, 4).
525
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
526
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
int m = 10;
int n = 4;
printf("Total number of possible sequences %d",
getTotalNumberOfSequences(m, n));
return 0;
}
Java
527
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
C#
528
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
// if length of sequence
// is more than the maximum
// value, special sequence
// cannot exist
else if (i < j)
T[i,j] = 0;
// If length of sequence is 1 then the
// number of special sequences is equal
// to the maximum value
// For example with maximum value 2 and
// length 1, there can be 2 special
// sequences {1}, {2}
else if (j == 1)
T[i,j] = i;
// otherwise calculate
else
T[i,j] = T[i - 1, j] + T[i / 2, j - 1];
}
}
return T[m,n];
}
// Driver Code
public static void Main ()
{
int m = 10;
int n = 4;
Console.WriteLine("Total number of possible sequences "+
getTotalNumberOfSequences(m, n));
}
}
// This code is contributed by anuj_67.
PHP
<?php
// PHP program to count total
// number of special sequences
// of length N where
// DP based function to find
// the number of special
// sequences
function getTotalNumberOfSequences($m, $n)
529
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
{
// define T and build in bottom
// manner to store number of
// special sequences of length
// n and maximum value m
$T = array(array());
for ($i = 0; $i < $m + 1; $i++)
{
for ($j = 0; $j < $n + 1; $j++)
{
// Base case : If length of
// sequence is 0 or maximum
// value is 0, there cannot
// exist any special sequence
if ($i == 0 or $j == 0)
$T[$i][$j] = 0;
// if length of sequence is
// more than the maximum value,
// special sequence cannot exist
else if ($i < $j)
$T[$i][$j] = 0;
// If length of sequence is
// 1 then the number of
// special sequences is equal
// to the maximum value
// For example with maximum
// value 2 and length 1, there
// can be 2 special sequences
// {1}, {2}
else if ($j == 1)
$T[$i][$j] = $i;
// otherwise calculate
else
$T[$i][$j] = $T[$i - 1][$j] +
$T[$i / 2][$j - 1];
}
}
return $T[$m][$n];
}
// Driver Code
$m = 10;
530
Chapter 73. Sequences of given length where every element is more than or equal to twice
of previous
$n = 4;
echo "Total number of possible sequences ",
getTotalNumberOfSequences($m, $n);
// This code is contributed by anuj_67.
?>
Output:
Source
https://www.geeksforgeeks.org/sequences-given-length-every-element-equal-twice-previous/
531
Chapter 74
Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ......, an, bn} without using extra space
- GeeksforGeeks
Given an array of 2n elements in the following format { a1, a2, a3, a4, ….., an, b1, b2, b3,
b4, …., bn }. The task is shuffle the array to {a1, b1, a2, b2, a3, b3, ……, an, bn } without
using extra space.
Examples:
Input : arr[] = { 1, 2, 9, 15 }
Output : 1 9 2 15
Input : arr[] = { 1, 2, 3, 4, 5, 6 }
Output : 1 4 2 5 3 6
532
Chapter 74. Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} without
using extra space
#include <bits/stdc++.h>
using namespace std;
// function to shuffle an array of size 2n
void shuffleArray(int a[], int n)
{
// Rotate the element to the left
for (int i = 0, q = 1, k = n; i < n; i++, k++, q++)
for (int j = k; j > i + q; j--)
swap(a[j-1], a[j]);
}
// Driven Program
int main()
{
int a[] = { 1, 3, 5, 7, 2, 4, 6, 8 };
int n = sizeof(a) / sizeof(a[0]);
shuffleArray(a, n/2);
for (int i = 0; i < n; i++)
cout << a[i] << " ";
return 0;
}
Java
533
Chapter 74. Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} without
using extra space
Python3
Output:
1 2 3 4 5 6 7 8
534
Chapter 74. Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} without
using extra space
arr1[] and arr2[]) and swap second half element of arr1[] with first half element of arr2[].
Recursively do this for arr1 and arr2.
Let us explain with the help of an example.
1. Let the array be a1, a2, a3, a4, b1, b2, b3, b4
2. Split the array into two halves: a1, a2, a3, a4 : b1, b2, b3, b4
3. Exchange element around the center: exchange a3, a4 with b1, b2 correspondingly.
you get: a1, a2, b1, b2, a3, a4, b3, b4
4. Recursively spilt a1, a2, b1, b2 into a1, a2 : b1, b2
then split a3, a4, b3, b4 into a3, a4 : b3, b4.
5. Exchange elements around the center for each subarray we get:
a1, b1, a2, b2 and a3, b3, a4, b4.
Note: This solution only handles the case when n = 2i where i = 0, 1, 2, …etc.
Below is implementation of this approach:
C++
535
Chapter 74. Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} without
using extra space
// Driven Program
int main()
{
int a[] = { 1, 3, 5, 7, 2, 4, 6, 8 };
int n = sizeof(a) / sizeof(a[0]);
shufleArray(a, 0, n - 1);
for (int i = 0; i < n; i++)
cout << a[i] << " ";
return 0;
}
Java
536
Chapter 74. Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} without
using extra space
Python3
537
Chapter 74. Shuffle 2n integers in format {a1, b1, a2, b2, a3, b3, ……, an, bn} without
using extra space
# Driver Code
a = [1, 3, 5, 7, 2, 4, 6, 8]
n = len(a)
shufleArray(a, 0, n - 1)
for i in range(0, n):
print(a[i], end = " ")
# This code is contributed by Smitha Dinesh Semwal
Output:
1 2 3 4 5 6 7 8
Source
https://www.geeksforgeeks.org/shuffle-2n-integers-format-a1-b1-a2-b2-a3-b3-bn-without-using-extra-space/
538
Chapter 75
Smallest number with given sum of digits and sum of square of digits - GeeksforGeeks
Given sum of digits and sum of square of digits . Find the smallest number with given
sum of digits and sum of the square of digits. The number should not contain more than
100 digits. Print -1 if no such number exists or if the number of digits is more than 100.
Examples:
Approach:
Since the smallest number can be of 100 digits, it cannot be stored. Hence the first step to
solve it will be to find the minimum number of digits which can give us the sum of digits
as and sum of the square of digits as . To find the minimum number of digits, we can
use Dynamic Programming. DP[a][b] signifies the minimum number of digits in a number
whose sum of the digits will be and sum of the square of digits will be . If there does
not exist any such number then DP[a][b] will be -1.
Since the number cannot exceed 100 digits, DP array will be of size 101*8101. Iterate for
every digit, and try all possible combination of digits which gives us the sum of digits as
and sum of the square of digits as . Store the minimum number of digits in DP[a][b] using
the below recurrence relation:
539
Chapter 75. Smallest number with given sum of digits and sum of square of digits
After getting the minimum number of digits, find the digits. To find the digits, check for all
combinations and print those digits which satisfies the condition below:
If the condition above is met by any of i, reduce by i and by i*i and break. Keep on
repeating the above process to find all the digits till is 0 and is 0.
Below is the C++ implementation of above approach:
540
Chapter 75. Smallest number with given sum of digits and sum of square of digits
// If the combination of digits cannot give sum as a
// and sum of square of digits as b
if (k != -1)
ans = min(ans, k + 1);
}
// Returns the minimum number of digits
return dp[a][b] = ans;
}
// Function to print the digits that gives
// sum as a and sum of square of digits as b
void printSmallestNumber(int a,int b)
{
// initialize the dp array as -1
memset(dp, -1, sizeof(dp));
// base condition
dp[0][0] = 0;
// function call to get the minimum number of digits
int k = minimumNumberOfDigits(a, b);
// When there does not exists any number
if (k == -1 || k > 100)
cout << "-1";
else {
// Printing the digits from the most significant digit
while (a > 0 && b > 0) {
// Trying all combinations
for (int i = 1; i <= 9; i++) {
// checking conditions for minimum digits
if (a >= i && b >= i * i &&
1 + dp[a - i][b - i * i] == dp[a][b]) {
cout << i;
a -= i;
b -= i * i;
break;
}
}
}
}
}
// Driver Code
541
Chapter 75. Smallest number with given sum of digits and sum of square of digits
int main()
{
int a = 18, b = 162;
// Function call to print the smallest number
printSmallestNumber(a,b);
}
Output:
99
Source
https://www.geeksforgeeks.org/smallest-number-with-given-sum-of-digits-and-sum-of-square-of-digits/
542
Chapter 76
Input: x = 4
Output: 2
Input: x = 11
Output: 3
There can be many ways to solve this problem. For example Babylonian Method is one way.
A Simple Solution to find floor of square root is to try all numbers starting from 1. For
every tried number i, if i*i is smaller than x, then increment i. We stop when i*i becomes
more than or equal to x. Below is the implementation of above idea.
C++
543
Chapter 76. Square root of an integer
Java
544
Chapter 76. Square root of an integer
}
}
// This code is contributed by Smitha Dinesh Semwal.
Python3
C#
// A C# program to
// find floor(sqrt(x))
using System;
class GFG
{
// Returns floor of
// square root of x
static int floorSqrt(int x)
{
// Base cases
if (x == 0 || x == 1)
return x;
545
Chapter 76. Square root of an integer
// Staring from 1, try all
// numbers until i*i is
// greater than or equal to x.
int i = 1, result = 1;
while (result <= x)
{
i++;
result = i * i;
}
return i - 1;
}
// Driver Code
static public void Main ()
{
int x = 11;
Console.WriteLine(floorSqrt(x));
}
}
// This code is contributed by ajit
PHP
<?php
// A PHP program to find floor(sqrt(x)
// Returns floor of square root of x
function floorSqrt($x)
{
// Base cases
if ($x == 0 || $x == 1)
return $x;
// Staring from 1, try all
// numbers until i*i is
// greater than or equal to x.
$i = 1;
$result = 1;
while ($result <= $x)
{
$i++;
$result = $i * $i;
}
return $i - 1;
}
546
Chapter 76. Square root of an integer
// Driver Code
$x = 11;
echo floorSqrt($x), "\n";
// This code is contributed by ajit
?>
Output :
Time complexity of the above solution is O(√ n). Thanks Fattepur Mahesh for suggesting
this solution.
A Better Solution to do Binary Search.
If r*r = r
Algorithm:
1) Start with ‘start’ = 0, end = ‘x’,
2) Do following while ‘start’ is smaller than or equal to ‘end’.
a) Compute ‘mid’ as (start + end)/2
b) compare mid*mid with x.
c) If x is equal to mid*mid, return mid.
d) If x is greater, do binary search between mid+1 and end. In this case, we also update
ans (Note that we need floor).
e) If x is smaller, do binary search between start and mid
Below is the implementation of above idea.
C/C++
547
Chapter 76. Square root of an integer
Java
548
Chapter 76. Square root of an integer
Python3
549
Chapter 76. Square root of an integer
if (mid*mid == x) :
return mid
# Since we need floor, we update
# answer when mid*mid is smaller
# than x, and move closer to sqrt(x)
if (mid * mid < x) :
start = mid + 1
ans = mid
else :
# If mid*mid is greater than x
end = mid
return ans
# driver code
x = 11
print(floorSqrt(x))
# This code is contributed by Nikita Tiwari.
C#
// A C# program to
// find floor(sqrt(x)
using System;
class GFG
{
public static int floorSqrt(int x)
{
// Base Cases
if (x == 0 || x == 1)
return x;
// Do Binary Search
// for floor(sqrt(x))
int start = 1, end = x, ans = 0;
while (start <= end)
{
int mid = (start + end) / 2;
// If x is a
// perfect square
if (mid * mid == x)
return mid;
550
Chapter 76. Square root of an integer
// Since we need floor, we
// update answer when mid *
// mid is smaller than x,
// and move closer to sqrt(x)
if (mid * mid < x)
{
start = mid + 1;
ans = mid;
}
// If mid*mid is
// greater than x
else
end = mid;
}
return ans;
}
// Driver Code
static public void Main ()
{
int x = 11;
Console.WriteLine(floorSqrt(x));
}
}
// This code is Contributed by m_kit
PHP
<?php
// A PHP program to find floor(sqrt(x)
// Returns floor of
// square root of x
function floorSqrt($x)
{
// Base cases
if ($x == 0 || $x == 1)
return $x;
// Do Binary Search
// for floor(sqrt(x))
$start = 1; $end = $x; $ans;
while ($start <= $end)
{
$mid = ($start + $end) / 2;
551
Chapter 76. Square root of an integer
// If x is a perfect square
if ($mid * $mid == $x)
return $mid;
// Since we need floor, we update
// answer when mid*mid is smaller
// than x, and move closer to sqrt(x)
if ($mid * $mid < $x)
{
$start = $mid + 1;
$ans = $mid;
}
// If mid*mid is
// greater than x
else
$end = $mid;
}
return $ans;
}
// Driver Code
$x = 11;
echo floorSqrt($x), "\n";
// This code is contributed by ajit
?>
Output :
552
Chapter 76. Square root of an integer
Source
https://www.geeksforgeeks.org/square-root-of-an-integer/
553
Chapter 77
Input : arr[] = { 2, 3, 5 }, B = 11
Output : 2 11
Explanation : Cost of picking maximum elements = {2 + (1 * 2) } + {3 + (2
* 2)} = 4 + 7 = 11 (which is equal to budget)
Input : arr[] = { 1, 2, 5, 6, 3 }, B = 90
Output : 4 54
554
Chapter 77. Sudo Placement | Placement Tour
555
Chapter 77. Sudo Placement | Placement Tour
// If the current Mid Value is an optimal
// value, then try to maximize it
if (canBeOptimalValue(mid, arr, N, B,
cumulativeValue)) {
ans = mid;
start = mid + 1;
}
else
end = mid - 1;
}
// Call Again to set the corresponding cumulative
// value for the optimal ans
canBeOptimalValue(ans, arr, N, B, cumulativeValue);
cout << ans << " " << cumulativeValue << endl;
}
// Driver Code
int main()
{
int arr[] = { 1, 2, 5, 6, 3 };
int N = sizeof(arr) / sizeof(arr[0]);
// Budget
int B = 90;
findNoOfElementsandValue(arr, N, B);
return 0;
}
Output:
4 54
Time Complexity: O(N * (log N)2 ), where N is the number of elements in the given array.
Source
https://www.geeksforgeeks.org/sudo-placement-placement-tour/
556
Chapter 78
Input : Q = 2
L = 3, R = 7
L = 10, R = 16
Output : 5
6
For the first query, valid numbers are 3, 4, 5, 6, and 7.
For the second query, valid numbers are 10, 11, 12, 13, 14 and 16.
557
Chapter 78. Sudo Placement | Range Queries
C++
558
Chapter 78. Sudo Placement | Range Queries
Java
559
Chapter 78. Sudo Placement | Range Queries
import java.util.*;
import java.io.*;
public class RangeQueries {
//Class to store the L and R range of a query
static class Query {
long L;
long R;
}
//It returns index of first element which is grater than searched value
//If searched element is bigger than any array element function
// returns first index after last element.
public static int upperBound(ArrayList<Long> validNumbers,
Long value)
{
int low = 0;
int high = validNumbers.size()-1;
while(low < high){
int mid = (low + high)/2;
if(value >= validNumbers.get(mid)){
low = mid+1;
} else {
high = mid;
}
}
return low;
}
public static void answerQueries(ArrayList<Query> queries){
// Set of Numbers having at most 3 set bits
// arranged in non-descending order
Set<Long> allNum = new HashSet<>();
//0 Set bits
allNum.add(0L);
//Iterate over all possible combinations of i, j, k for
// 60 bits. And add all the numbers with 0, 1 or 2 set bits into
// the set allNum.
for(int i=0; i<=60; i++){
for(int j=0; j<=60; j++){
for(int k=0; k<=60; k++){
//For one set bit, check if i, j, k are equal
//if yes, then set that bit and add it to the set
560
Chapter 78. Sudo Placement | Range Queries
561
Chapter 78. Sudo Placement | Range Queries
R = temp;
}
if(L == 0){
int indxOfLastNum = upperBound(validNumbers, R);
System.out.println(indxOfLastNum+1);
}
else {
int indxOfFirstNum = upperBound(validNumbers, L);
int indxOfLastNum = upperBound(validNumbers, R);
System.out.println((indxOfLastNum - indxOfFirstNum +1));
}
}
}
public static void main(String[] args){
int Q = 2;
ArrayList<Query> queries = new ArrayList<>();
Query q1 = new Query();
q1.L = 3;
q1.R = 7;
Query q2 = new Query();
q2.L = 10;
q2.R = 16;
queries.add(q1);
queries.add(q2);
answerQueries(queries);
}
}
Source
https://www.geeksforgeeks.org/sudo-placement-range-queries/
562
Chapter 79
563
Chapter 79. The Skyline Problem using Divide and Conquer algorithm
A Simple Solution is to initialize skyline or result as empty, then one by one add buildings
to skyline. A building is added by first finding the overlapping strip(s). If there are no
overlapping strips, the new building adds new strip(s). If overlapping strip is found, then
height of the existing strip may increase. Time complexity of this solution is O(n2 )
We can find Skyline in Θ(nLogn) time using Divide and Conquer. The idea is similar to
Merge Sort, divide the given set of buildings in two subsets. Recursively construct skyline
for two halves and finally merge the two skylines.
How to Merge two Skylines?
The idea is similar to merge of merge sort, start from first strips of two skylines, compare
x coordinates. Pick the strip with smaller x coordinate and add it to result. The height of
added strip is considered as maximum of current heights from skyline1 and skyline2.
Example to show working of merge:
Skyline1 = {(1, 11), (3, 13), (9, 0), (12, 7), (16, 0)}
Skyline2 = {(14, 3), (19, 18), (22, 3), (23, 13), (29, 0)}
Result = {}
h1 = 0, h2 = 0
Compare (1, 11) and (14, 3). Since first strip has smaller left x,
add it to result and increment index for Skyline1.
h1 = 11, New Height = max(11, 0)
Result = {(1, 11)}
Compare (3, 13) and (14, 3). Since first strip has smaller left x,
add it to result and increment index for Skyline1
h1 = 13, New Height = max(13, 0)
Result = {(1, 11), (3, 13)}
Compare (16, 0) and (14, 3). Since second strip has smaller left x,
it is added to result.
h2 = 3, New Height = max(7, 3) = 7
Result = {(1, 11), (3, 13), (9, 0), (12, 7), (14, 7)}
564
Chapter 79. The Skyline Problem using Divide and Conquer algorithm
Compare (16, 0) and (19, 18). Since first strip has smaller left x,
it is added to result.
h1 = 0, New Height = max(0, 3) = 3
Result = {(1, 11), (3, 13), (9, 0), (12, 7), (14, 3), (16, 3)}
One observation about above output is, the strip (16, 3) is redundant
(There is already an strip of same height). We remove all redundant
strips.
Result = {(1, 11), (3, 13), (9, 0), (12, 7), (14, 3), (19, 18),
(22, 3), (23, 13), (29, 0)}
565
Chapter 79. The Skyline Problem using Divide and Conquer algorithm
566
Chapter 79. The Skyline Problem using Divide and Conquer algorithm
}
};
// This function returns skyline for a given array of buildings
// arr[l..h]. This function is similar to mergeSort().
SkyLine *findSkyline(Building arr[], int l, int h)
{
if (l == h)
{
SkyLine *res = new SkyLine(2);
res->append(new Strip(arr[l].left, arr[l].ht));
res->append(new Strip(arr[l].right, 0));
return res;
}
int mid = (l + h)/2;
// Recur for left and right halves and merge the two results
SkyLine *sl = findSkyline(arr, l, mid);
SkyLine *sr = findSkyline(arr, mid+1, h);
SkyLine *res = sl->Merge(sr);
// To avoid memory leak
delete sl;
delete sr;
// Return merged skyline
return res;
}
// Similar to merge() in MergeSort
// This function merges another skyline 'other' to the skyline
// for which it is called. The function returns pointer to
// the resultant skyline
SkyLine *SkyLine::Merge(SkyLine *other)
{
// Create a resultant skyline with capacity as sum of two
// skylines
SkyLine *res = new SkyLine(this->n + other->n);
// To store current heights of two skylines
int h1 = 0, h2 = 0;
// Indexes of strips in two skylines
int i = 0, j = 0;
while (i < this->n && j < other->n)
{
// Compare x coordinates of left sides of two
567
Chapter 79. The Skyline Problem using Divide and Conquer algorithm
568
Chapter 79. The Skyline Problem using Divide and Conquer algorithm
ptr->print();
return 0;
}
References:
http://faculty.kfupm.edu.sa/ics/darwish/stuff/ics353handouts/Ch4Ch5.pdf
www.cs.ucf.edu/~sarahb/COP3503/Lectures/DivideAndConquer.ppt
This article is contributed Abhay Rathi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
https://www.geeksforgeeks.org/the-skyline-problem-using-divide-and-conquer-algorithm/
569
Chapter 80
From the above examples, it is obvious that the strategy of dividing the boards into k equal
partitions won’t work for all the cases. We can observe that the problem can be broken
down into: Given an array A of non-negative integers and a positive integer k, we have to
divide A into k of fewer partitions such that the maximum sum of the elements in a partition,
overall partitions is minimized. So for the second example above, possible divisions are:
* One partition: so time is 100.
* Two partitions: (10) & (20, 30, 40), so time is 90. Similarly we can put the first divider
after 20 (=> time 70) or 30 (=> time 60); so this means the minimum time: (100, 90, 70,
60) is 60.
570
Chapter 80. The painter’s partition problem
A brute force solution is to consider all possible set of contiguous partitions and calculate
the maximum sum partition in each case and return the minimum of all these cases.
1) Optimal Substructure:
We can implement the naive solution using recursion with the following optimal substructure
property:
Assuming that we already have k-1 partitions in place (using k-2 dividers), we now have to
put the k-1 th divider to get k partitions.
How can we do this? We can put the k-1 th divider between the i th and i+1 th element
where i = 1 to n. Please note that putting it before the first element is the same as putting
it after the last element.
The total cost of this arrangement can be calculated as the maximum of the following:
a) The cost of the last partition: sum(Ai..An), where the k-1 th divider is
before element i.
b) The maximum cost of any partition already formed to the left of the k-1 th divider.
Here a) can be found out using a simple helper function to calculate sum
of elements between two indices in the array. How to find out b) ?
We can observe that b) actually is to place the k-2 separators as fairly as
possible, so it is a subproblem of the given problem. Thus we can write the optimal
substructure property as the following recurrence relation:
C++
571
Chapter 80. The painter’s partition problem
{
int total = 0;
for (int i = from; i <= to; i++)
total += arr[i];
return total;
}
// for n boards and k partitions
int partition(int arr[], int n, int k)
{
// base cases
if (k == 1) // one partition
return sum(arr, 0, n - 1);
if (n == 1) // one board
return arr[0];
int best = INT_MAX;
// find minimum of all possible maximum
// k-1 partitions to the left of arr[i],
// with i elements, put k-1 th divider
// between arr[i-1] & arr[i] to get k-th
// partition
for (int i = 1; i <= n; i++)
best = min(best, max(partition(arr, i, k - 1),
sum(arr, i, n - 1)));
return best;
}
int main()
{
int arr[] = { 10, 20, 60, 50, 30, 40 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 3;
cout << partition(arr, n, k) << endl;
return 0;
}
Java
572
Chapter 80. The painter’s partition problem
C#
573
Chapter 80. The painter’s partition problem
574
Chapter 80. The painter’s partition problem
PHP
<?php
// PHP program for The
// painter's partition problem
// function to calculate sum
// between two indices in array
function sum($arr, $from, $to)
{
$total = 0;
for ($i = $from; $i <= $to; $i++)
$total += $arr[$i];
return $total;
}
// for n boards
// and k partitions
function partition($arr, $n, $k)
{
// base cases
if ($k == 1) // one partition
return sum($arr, 0, $n - 1);
if ($n == 1) // one board
return $arr[0];
$best = PHP_INT_MAX;
// find minimum of all possible
// maximum k-1 partitions to the
// left of arr[i], with i elements,
// put k-1 th divider between
// arr[i-1] & arr[i] to get k-th
// partition
for ($i = 1; $i <= $n; $i++)
$best = min($best,
max(partition($arr, $i, $k - 1),
sum($arr, $i, $n - 1)));
return $best;
}
575
Chapter 80. The painter’s partition problem
// Driver Code
$arr = array(10, 20, 60,
50, 30, 40);
$n = sizeof($arr);
$k = 3;
echo partition($arr, $n, $k), "\n";
// This code is contributed by ajit
?>
Output :
90
T(4, 3)
/ / \ ..
T(1, 2) T(2, 2) T(3, 2)
/.. /..
T(1, 1) T(1, 1)
We can observe that many subproblems like T(1, 1) in the above problem are being solved
again and again. Because of these two properties of this problem, we can solve it using
dynamic programming, either by top down memoized method or bottom up
tabular method. Following is the bottom up tabular implementation:
C++
576
Chapter 80. The painter’s partition problem
}
// bottom up tabular dp
int findMax(int arr[], int n, int k)
{
// initialize table
int dp[k + 1][n + 1] = { 0 };
// base cases
// k=1
for (int i = 1; i <= n; i++)
dp[1][i] = sum(arr, 0, i - 1);
// n=1
for (int i = 1; i <= k; i++)
dp[i][1] = arr[0];
// 2 to k partitions
for (int i = 2; i <= k; i++) { // 2 to n boards
for (int j = 2; j <= n; j++) {
// track minimum
int best = INT_MAX;
// i-1 th separator before position arr[p=1..j]
for (int p = 1; p <= j; p++)
best = min(best, max(dp[i - 1][p],
sum(arr, p, j - 1)));
dp[i][j] = best;
}
}
// required
return dp[k][n];
}
// driver function
int main()
{
int arr[] = { 10, 20, 60, 50, 30, 40 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 3;
cout << findMax(arr, n, k) << endl;
return 0;
}
Java
577
Chapter 80. The painter’s partition problem
578
Chapter 80. The painter’s partition problem
// required
return dp[k][n];
}
// Driver code
public static void main(String args[])
{
int arr[] = { 10, 20, 60, 50, 30, 40 };
// Calculate size of array.
int n = arr.length;
int k = 3;
System.out.println(findMax(arr, n, k));
}
}
// This code is contributed by Sahil_Bansall
C#
579
Chapter 80. The painter’s partition problem
PHP
<?php
// A DP based PHP program for
// painter's partition problem
// function to calculate sum
// between two indices in array
function sum($arr, $from, $to)
{
$total = 0;
580
Chapter 80. The painter’s partition problem
581
Chapter 80. The painter’s partition problem
$n = sizeof($arr);
$k = 3;
echo findMax($arr, $n, $k) ,"\n";
// This code is contribted by m_kit
?>
Output:
90
Optimizations:
int sum[n+1] = {0};
// sum from 1 to i elements of arr
for (int i = 1; i <= n; i++)
sum[i] = sum[i-1] + arr[i-1];
for (int i = 1; i <= n; i++)
dp[1][i] = sum[i];
and using it to calculate the result as:
best = min(best, max(dp[i-1][p], sum[j] - sum[p]));
2) Though here we consider to divide A into k or fewer partitions, we can observe that
the optimal case always occurs when we divide A into exactly k partitions. So we can use:
582
Chapter 80. The painter’s partition problem
References:
https://articles.leetcode.com/the-painters-partition-problem/
Asked in: Google, CodeNation
Improved By : vt_m, jit_t
Source
https://www.geeksforgeeks.org/painters-partition-problem/
583
Chapter 81
In the previous post we discussed a dynamic programming based approach having time
584
Chapter 81. The painter’s partition problem | Set 2
We also know that the values in this range must be in sorted order. Here our target value
is the maximum sum of a contiguous section in the optimal allocation of boards. Now how
can we apply binary search for this? We can fix the possible low to high range for the target
value and narrow down our search to get the optimal allocation.
We can see that the highest possible value in this range is the sum of all the elementsin the
array and this happens when we allot 1 painter all the sections of the board. The lowest
possible value of this range is the maximum value of the array max, as in this allocation we
can allot max to one painter and divide the other sections such
that the cost of them is less than or equal to max and as close as possible to max. Now if we
consider we use x painters in the above scenarios, it is obvious that as the value in the range
increases, the value of x decreases and vice-versa. From this we can find the target value
when x=k and use a helper function to find x, the minimum number of painters required
when the maximum length of section a painter can paint is given.
C++
585
Chapter 81. The painter’s partition problem | Set 2
Java
586
Chapter 81. The painter’s partition problem | Set 2
587
Chapter 81. The painter’s partition problem | Set 2
C#
588
Chapter 81. The painter’s partition problem | Set 2
589
Chapter 81. The painter’s partition problem | Set 2
PHP
<?php
// PHP program for painter's
// partition problem
590
Chapter 81. The painter’s partition problem | Set 2
// return the maximum
// element from the array
function getMax($arr, $n)
{
$max = PHP_INT_MIN;
for ($i = 0; $i < $n; $i++)
if ($arr[$i] > $max)
$max = $arr[$i];
return $max;
}
// return the sum of the
// elements in the array
function getSum($arr, $n)
{
$total = 0;
for ($i = 0; $i < $n; $i++)
$total += $arr[$i];
return $total;
}
// find minimum required painters
// for given maxlen which is the
// maximum length a painter can paint
function numberOfPainters($arr, $n,
$maxLen)
{
$total = 0; $numPainters = 1;
for ($i = 0; $i < $n; $i++)
{
$total += $arr[$i];
if ($total > $maxLen)
{
// for next count
$total = $arr[$i];
$numPainters++;
}
}
return $numPainters;
}
function partition($arr, $n, $k)
{
591
Chapter 81. The painter’s partition problem | Set 2
Output :
17
For better understanding, please trace the example given in the program in pen and paper.
592
Chapter 81. The painter’s partition problem | Set 2
Source
https://www.geeksforgeeks.org/painters-partition-problem-set-2/
593
Chapter 82
594
Chapter 82. Tiling Problem using Divide and Conquer algorithm
2) Place a L shaped tile at the center such that it does not cover
the n/2 * n/2 subsquare that has a missing square. Now all four
subsquares of size n/2 x n/2 have a missing cell (a cell that doesn't
need to be filled). See figure 2 below.
3) Solve the problem recursively for following four. Let p1, p2, p3 and
p4 be positions of the 4 missing cells in 4 squares.
a) Tile(n/2, p1)
b) Tile(n/2, p2)
c) Tile(n/2, p3)
d) Tile(n/2, p3)
595
Chapter 82. Tiling Problem using Divide and Conquer algorithm
Time Complexity:
596
Chapter 82. Tiling Problem using Divide and Conquer algorithm
Recurrence relation for above recursive algorithm can be written as below. C is a constant.
T(n) = 4T(n/2) + C
The above recursion can be solved using Master Methodand time complexity is O(n2 )
How does this work?
The working of Divide and Conquer algorithm can be proved using Mathematical Induction.
Let the input square be of size 2k x 2k where k >=1.
Base Case: We know that the problem can be solved for k = 1. We have a 2 x 2 square
with one cell missing.
Induction Hypothesis: Let the problem can be solved for k-1.
Now we need to prove to prove that the problem can be solved for k if it can be solved for
k-1. For k, we put a L shaped tile in middle and we have four subsqures with dimension
2k-1 x 2k-1 as shown in figure 2 above. So if we can solve 4 subsquares, we can solve the
complete square.
References:
http://www.comp.nus.edu.sg/~sanjay/cs3230/dandc.pdf
This article is contributed by Abhay Rathi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
https://www.geeksforgeeks.org/tiling-problem-using-divide-and-conquer-algorithm/
597
Chapter 83
Unbounded Binary Search Example (Find the point where a monotonically increasing func-
tion becomes positive first time) - GeeksforGeeks
Given a function ‘int f(unsigned int x)’ which takes a non-negative integer ‘x’ as input
and returns an integer as output. The function is monotonically increasing with respect to
value of x, i.e., the value of f(x+1) is greater than f(x) for every input x. Find the value ‘n’
where f() becomes positive for the first time. Since f() is monotonically increasing, values of
f(n+1), f(n+2),… must be positive and values of f(n-2), f(n-3), .. must be negative.
Find n in O(logn) time, you may assume that f(x) can be evaluated in O(1) time for any
input x.
A simple solution is to start from i equals to 0 and one by one calculate value of f(i) for
1, 2, 3, 4 .. etc until we find a positive f(i). This works, but takes O(n) time.
Can we apply Binary Search to find n in O(Logn) time? We can’t directly apply
Binary Search as we don’t have an upper limit or high index. The idea is to do repeated
doubling until we find a positive value, i.e., check values of f() for following values until f(i)
becomes positive.
f(0)
f(1)
f(2)
598
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
f(4)
f(8)
f(16)
f(32)
....
....
f(high)
Let 'high' be the value of i when f() becomes positive for first time.
Can we apply Binary Search to find n after finding ‘high’? We can apply Binary Search
now, we can use ‘high/2’ as low and ‘high’ as high indexes in binary search. The result n
must lie between ‘high/2’ and ‘high’.
Number of steps for finding ‘high’ is O(Logn). So we can find ‘high’ in O(Logn) time. What
about time taken by Binary Search between high/2 and high? The value of ‘high’ must be
less than 2*n. The number of elements between high/2 and high must be O(n). Therefore,
time complexity of Binary Search is O(Logn) and overall time complexity is 2*O(Logn)
which is O(Logn).
#include <stdio.h>
int binarySearch(int low, int high); // prototype
// Let's take an example function as f(x) = x^2 - 10*x - 20
// Note that f(x) can be any monotonocally increasing function
int f(int x) { return (x*x - 10*x - 20); }
// Returns the value x where above function f() becomes positive
// first time.
int findFirstPositive()
{
// When first value itself is positive
if (f(0) > 0)
return 0;
// Find 'high' for binary search by repeated doubling
int i = 1;
while (f(i) <= 0)
i = i*2;
// Call binary search
return binarySearch(i/2, i);
}
// Searches first positive value of f(i) where low <= i <= high
int binarySearch(int low, int high)
{
599
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
Java
600
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
// Find 'high' for binary search
// by repeated doubling
int i = 1;
while (f(i) <= 0)
i = i * 2;
// Call binary search
return binarySearch(i / 2, i);
}
// Searches first positive value of
// f(i) where low <= i <= high
public static int binarySearch(int low, int high)
{
if (high >= low)
{
/* mid = (low + high)/2 */
int mid = low + (high - low)/2;
// If f(mid) is greater than 0 and
// one of the following two
// conditions is true:
// a) mid is equal to low
// b) f(mid-1) is negative
if (f(mid) > 0 && (mid == low || f(mid-1) <= 0))
return mid;
// If f(mid) is smaller than or equal to 0
if (f(mid) <= 0)
return binarySearch((mid + 1), high);
else // f(mid) > 0
return binarySearch(low, (mid -1));
}
/* Return -1 if there is no positive
value in given range */
return -1;
}
// driver code
public static void main(String[] args)
{
System.out.print ("The value n where f() "+
"becomes positive first is "+
findFirstPositive());
}
}
601
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
// This code is contributed by rishabh_jain
Python3
602
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
C#
603
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
PHP
<?php
// PHP program for Binary Search
// Let's take an example function
// as f(x) = x^2 - 10*x - 20
604
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
605
Chapter 83. Unbounded Binary Search Example (Find the point where a monotonically
increasing function becomes positive first time)
Output :
Related Article:
Exponential Search
Improved By : nitin mittal, Sam007
Source
https://www.geeksforgeeks.org/find-the-point-where-a-function-becomes-negative/
606
Chapter 84
Input : x = 2, n = 3
Output : 8
Input : x = 7, n = 2
Output : 49
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);
607
Chapter 84. Write a program to calculate pow(x,n)
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));
return 0;
}
Java
class GFG {
/* Function to calculate x raised to the power y */
static int power(int x, 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 */
public static void main(String[] args)
{
int x = 2;
int y = 3;
System.out.printf("%d", power(x, y));
}
}
// This code is contributed by Smitha Dinesh Semwal
Python3
608
Chapter 84. Write a program to calculate pow(x,n)
if (y == 0): return 1
elif (int(y % 2) == 0):
return (power(x, int(y / 2)) *
power(x, int(y / 2)))
else:
return (x * power(x, int(y / 2)) *
power(x, int(y / 2)))
# Driver Code
x = 2; y = 3
print(power(x, y))
# This code is contributed by Smitha Dinesh Semwal.
C#
using System;
public class GFG {
// Function to calculate x raised to the power y
static int power(int x, 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
public static void Main()
{
int x = 2;
int y = 3;
Console.Write(power(x, y));
}
}
// This code is contributed by shiv_bhakt.
PHP
<?php
609
Chapter 84. Write a program to calculate pow(x,n)
// Function to calculate x
// raised to the power y
function power($x, $y)
{
if ($y == 0)
return 1;
else if ($y % 2 == 0)
return power($x, (int)$y / 2) *
power($x, (int)$y / 2);
else
return $x * power($x, (int)$y / 2) *
power($x, (int)$y / 2);
}
// Driver Code
$x = 2;
$y = 3;
echo power($x, $y);
// This code is contributed by ajit
?>
Output :
610
Chapter 84. Write a program to calculate pow(x,n)
Java
611
Chapter 84. Write a program to calculate pow(x,n)
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 */
public static void main(String[] args)
{
float x = 2;
int y = -3;
System.out.printf("%f", power(x, y));
}
}
// This code is contributed by Smitha Dinesh Semwal.
Python3
C#
612
Chapter 84. Write a program to calculate pow(x,n)
PHP
<?php
// Extended version of power
// function that can work
// for float x and negative y
function power($x, $y)
{
$temp;
if( $y == 0)
613
Chapter 84. Write a program to calculate pow(x,n)
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;
}
}
// Driver Code
$x = 2;
$y = -3;
echo power($x, $y);
// This code is contributed by ajit
?>
Output :
0.125000
Source
https://www.geeksforgeeks.org/write-a-c-program-to-calculate-powxn/
614
Chapter 85
Write you own Power without using multiplication(*) and division(/) operators - Geeks-
forGeeks
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)
C
#include<stdio.h>
/* 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++)
615
Chapter 85. Write you own Power without using multiplication(*) and division(/)
operators
{
answer += increment;
}
increment = answer;
}
return answer;
}
/* driver program to test above function */
int main()
{
printf("\n %d", pow(5, 3));
getchar();
return 0;
}
Java
import java.io.*;
class GFG {
/* Works only if a >= 0 and b >= 0 */
static 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;
}
// driver program to test above function
public static void main(String[] args)
{
System.out.println(pow(5, 3));
}
}
616
Chapter 85. Write you own Power without using multiplication(*) and division(/)
operators
// This code is contributed by vt_m.
Python
C#
using System;
class GFG
{
/* Works only if a >= 0 and b >= 0 */
static 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;
617
Chapter 85. Write you own Power without using multiplication(*) and division(/)
operators
}
increment = answer;
}
return answer;
}
// driver program to test
// above function
public static void Main()
{
Console.Write(pow(5, 3));
}
}
// This code is contributed by Sam007
PHP
<?php
// Works only if a >= 0
// and b >= 0
function poww($a, $b)
{
if ($b == 0)
return 1;
$answer = $a;
$increment = $a;
$i;
$j;
for($i = 1; $i < $b; $i++)
{
for($j = 1; $j < $a; $j++)
{
$answer += $increment;
}
$increment = $answer;
}
return $answer;
}
// Driver Code
echo( poww(5, 3));
// This code is contributed by nitin mittal.
?>
618
Chapter 85. Write you own Power without using multiplication(*) and division(/)
operators
Ouput :
125
#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;
}
Java
import java.io.*;
class GFG {
/* A recursive function to get a^b
619
Chapter 85. Write you own Power without using multiplication(*) and division(/)
operators
Python
def pow(a,b):
if(b):
return multiply(a, pow(a, b-1));
else:
return 1;
# A recursive function to get x*y *
def multiply(x, y):
if (y):
return (x + multiply(x, y-1));
else:
return 0;
# driver program to test above functions *
print(pow(5, 3));
620
Chapter 85. Write you own Power without using multiplication(*) and division(/)
operators
# This code is contributed
# by Sam007
C#
using System;
class GFG
{
/* A recursive function to get a^b
Works only if a >= 0 and b >= 0 */
static int pow(int a, int b)
{
if (b > 0)
return multiply(a, pow(a, b - 1));
else
return 1;
}
/* A recursive function to get x*y */
static int multiply(int x, int y)
{
if (y > 0)
return (x + multiply(x, y - 1));
else
return 0;
}
/* driver program to test above functions */
public static void Main()
{
Console.Write(pow(5, 3));
}
}
// This code is contributed by Sam007
PHP
<?php
/* A recursive function to get a^b
Works only if a >= 0 and b >= 0 */
621
Chapter 85. Write you own Power without using multiplication(*) and division(/)
operators
Ouput :
125
Source
https://www.geeksforgeeks.org/write-you-own-power-without-using-multiplication-and-division/
622