0% found this document useful (0 votes)
15 views22 pages

Divide and Conqure Cheatsheet

The document outlines various sorting and searching algorithms including Merge Sort, Quicksort, and Binary Search, along with their implementations in Java. It provides detailed code snippets for each algorithm, demonstrating their functionality and efficiency. Additionally, it includes utility functions for tasks like finding peaks in arrays and checking if an array is sorted.

Uploaded by

Ankita Pimpalkar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views22 pages

Divide and Conqure Cheatsheet

The document outlines various sorting and searching algorithms including Merge Sort, Quicksort, and Binary Search, along with their implementations in Java. It provides detailed code snippets for each algorithm, demonstrating their functionality and efficiency. Additionally, it includes utility functions for tasks like finding peaks in arrays and checking if an array is sorted.

Uploaded by

Ankita Pimpalkar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

● Merge Sort Algorithm if(graph[path[pos - 1]][v] == 0)

● Iterative Merge Sort Algorithm (Bottom-up return false;


Merge Sort) for(int i=0;i<pos;i++)
● Quicksort Algorithm {
● Hybrid QuickSort Algorithm if(path[i] == v)
● Quicksort using Dutch National Flag Algorithm return false;
● Quicksort algorithm using Hoare’s partitioning }
scheme return true;
● Inversion count of an array }
● Segregate positive and negative integers using boolean hamCycleUtil(int graph[][],int path[], int pos)
merge sort {
● Iterative Implementation of Quicksort if(pos == V)
● Binary Search Algorithm {
● Find the number of rotations in a circularly if(graph[path[pos - 1]][path[0]] == 1)
sorted array return true;
● Search an element in a circularly sorted array else
● Find the first or last occurrence of a given return false;
number in a sorted array }
● Count occurrences of a number in a sorted for(int v = 1;v<V;v++)
array with duplicates {
● Find the smallest missing element from a if(isSafe(v,graph,path,pos))
sorted array {
● Find floor and ceil of a number in a sorted path[pos] = v;
integer array if(hamCycleUtil(graph,path,pos+1) == true)
● Search in a nearly sorted array in logarithmic return true;
time
● Find the number of 1’s in a sorted binary array path[pos] = -1;
● Find the peak element in an array }
● Maximum Subarray Sum using Divide and }
Conquer return false;
● Efficiently implement power function }
● Find the missing term in a sequence in int hamCycle(int graph[][])
logarithmic time {
● Find floor and ceil of a number in a sorted path = new int[V];
array (Recursive solution) for(int i=0;i<V;i++)
● Find the frequency of each element in a sorted {
array containing duplicates path[i] = -1;
● Find the square root of a number using a }
binary search path[0] = 0;
● Division of two numbers using binary search if(hamCycleUtil(graph,path,1) == false)
algorithm {
● Find the odd occurring element in an array in System.out.println(("\n No solution exists"));
logarithmic time return 0;
● Find pairs with difference `k` in an array | }
Constant Space Solution printSolution(path);
● Find `k` closest elements to a given value in an return 1;
array }
● Find the minimum and maximum element in an /* A utility function to print solution */
array using Divide and Conquer void printSolution(int path[])
● Longest Common Prefix (LCP) Problem {
● Binary Search in C++ STL and Java Collections System.out.println("Solution Exists: Following" +
● Ternary Search vs Binary search " is one Hamiltonian Cycle");
● Exponential search for (int i = 0; i < V; i++)
● Unbounded Binary Search System.out.print(" " + path[i] + " ");
● Interpolation search // Let us print the first vertex again to show the
● Introsort Algorithm — Overview and C++ // complete cycle
Implementation System.out.println(" " + path[0] + " ");
● Efficiently merge `k` sorted linked lists }
● Merge sort algorithm for a singly linked list }
● Sort a doubly-linked list using merge sort
● Find the square of a number without using the peakFinder
multiplication and division operator public class peakFinder {
public static int findPeak(int[] arr, int start,int end)
hamiltonianCycle {
public class hamiltonianCycle { int mid = (start+end)/2;
final int V = 5; if ((mid == 0 || arr[mid - 1] <= arr[mid])
int path[]; && (mid == arr.length - 1 || arr[mid + 1] <=
arr[mid]))
boolean isSafe(int v,int graph[][], int path[],int pos)
{

1
// if((mid>0 && arr[mid]>arr[mid - 1]) || (mid<arr.length - 1 {
&& arr[mid]>arr[mid+1])) int k = low, i = low, j = mid + 1;
{
return mid; // while there are elements in the left and
} right runs
else if(mid< arr.length - 1 && arr[mid+1]>arr[mid]) while (i <= mid && j <= high)
{ {
return findPeak(arr,mid+1,end); if (arr[i] <= arr[j]) {
} aux[k++] = arr[i++];
else }
{ else {
return findPeak(arr,start,mid-1); aux[k++] = arr[j++];
} }
} }
public static int[] findPeak2d(int[][] arr)
{ // copy remaining elements
int stcol=0; while (i <= mid) {
int endcol=arr[0].length - 1; aux[k++] = arr[i++];
}
while(stcol<=endcol)
{ // No need to copy the second half
int mid_col = stcol+(endcol-stcol)/2; (since the remaining items
int max = 0; // are already in their correct position in
int max_index = 0; the auxiliary array)
for(int i=0;i<arr.length;i++)
{ // copy back to the original array to
if(arr[i][mid_col] > max) { reflect sorted order
max = arr[i][mid_col]; for (i = low; i <= high; i++) {
max_index = i; arr[i] = aux[i];
} }
}
}
// Sort array `arr[low…high]` using auxiliary array
boolean valid_left = mid_col > stcol && `aux`
(arr[max_index][mid_col - 1] > arr[max_index][mid_col]); public static void mergesort(int[] arr, int[] aux, int
boolean valid_right = mid_col < endcol && low, int high)
(arr[max_index][mid_col + 1] > arr[max_index][mid_col]); {
// base case
if(!valid_left && !valid_right) if (high <= low) { // if run
return new int[] { max_index, mid_col }; size <= 1
else if (valid_left) { return;
endcol = mid_col - 1; }
}
else { // find midpoint
stcol = mid_col + 1; int mid = (low + ((high - low) >> 1));
}
} // recursively split runs into two halves
return new int[] { -1, -1 }; until run size <= 1,
} // then merge them and return up the
public static void printMatrix(int[][] matrix) { call chain
for (int[] row : matrix) {
for (int element : row) { mergesort(arr, aux, low, mid);
System.out.print(element + " "); // split/merge left half
} mergesort(arr, aux, mid + 1, high);
System.out.println(); // split/merge right half
}
} merge(arr, aux, low, mid, high);
} // merge the two half runs
}

MERGE SORT O(n.log(n) // Function to check if arr is sorted in ascending


order or not
import java.util.Arrays; public static boolean isSorted(int[] arr)
{
class Main int prev = arr[0];
{ for (int i = 1; i < arr.length; i++)
// Merge two sorted subarrays `arr[low … mid]` {
and `arr[mid+1 … high]` if (prev > arr[i])
public static void merge(int[] arr, int[] aux, int low, {
int mid, int high)

2
// Iteratively sort subarray `A[low…high]` using a
System.out.println("MergeSort Fails!!"); temporary array
return false; public static void mergesort(int[] A)
} {
prev = arr[i]; int low = 0;
} int high = A.length - 1;

return true; // sort array `A[]` using a temporary


} array `temp`
int[] temp = Arrays.copyOf(A, A.length);
// Implementation of merge sort algorithm in Java
public static void main(String[] args) // divide the array into blocks of size `m`
{ // m = [1, 2, 4, 8, 16…]
int[] arr = { 12, 3, 18, 24, 0, 5, -2 }; for (int m = 1; m <= high - low; m = 2*m)
int[] aux = Arrays.copyOf(arr, arr.length); {
// for m = 1, i = 0, 2, 4, 6, 8 …
// sort array `arr` using auxiliary array // for m = 2, i = 0, 4, 8, 12 …
`aux` // for m = 4, i = 0, 8, 16 …
mergesort(arr, aux, 0, arr.length - 1); // …
for (int i = low; i < high; i +=
if (isSorted(arr)) { 2*m)
{
System.out.println(Arrays.toString(arr)); int from = i;
} int mid = i + m - 1;
} int to = Integer.min(i
} + 2*m - 1, high);

Iterative merge sort merge(A, temp,


from, mid, to);
import java.util.Arrays; }
}
class Main }
{
// Merge two sorted subarrays `A[from…mid]` and // Iterative implementation of merge sort
`A[mid+1…to]` public static void main(String[] args)
public static void merge(int[] A, int[] temp, int from, {
int mid, int to) int[] A = { 5, 7, -9, 3, -4, 2, 8 };
{
int k = from, i = from, j = mid + 1; System.out.println("Original array: " +
Arrays.toString(A));
// loop till no elements are left in the left mergesort(A);
and right runs System.out.println("Modified array: " +
while (i <= mid && j <= to) Arrays.toString(A));
{ }
if (A[i] < A[j]) { }
temp[k++] = A[i++];
} QuickSort O(n2)
else {
temp[k++] = A[j++];
} import java.util.Arrays;
}
class Main
// copy remaining elements {
while (i < A.length && i <= mid) { public static void swap (int[] arr, int i, int j)
temp[k++] = A[i++]; {
} int temp = arr[i];
arr[i] = arr[j];
/* no need to copy the second half arr[j] = temp;
(since the remaining items }
are already in their correct position in
the temporary array) */ // Partition using the Lomuto partition scheme
public static int partition(int[] a, int start, int end)
// copy back to the original array to {
reflect sorted order // Pick the rightmost element as a pivot from the array
for (i = from; i <= to; i++) { int pivot = a[end];
A[i] = temp[i];
} // elements less than the pivot will be pushed to the left
} of `pIndex`
// elements more than the pivot will be pushed to the
right of `pIndex`

3
// equal elements can go either way }
int pIndex = start;
public int getX() { return x; }
// each time we find an element less than or equal to the public int getY() { return y; }
pivot, }
// `pIndex` is incremented, and that element would be
placed class Main
// before the pivot. {
for (int i = start; i < end; i++) public static void swap (int[] nums, int i, int j)
{ {
if (a[i] <= pivot) int temp = nums[i];
{ nums[i] = nums[j];
swap(a, i, pIndex); nums[j] = temp;
pIndex++; }
}
} // Partition routine using the Dutch national flag
algorithm
// swap `pIndex` with pivot public static Pair partition(int[] nums, int start, int
swap(a, end, pIndex); end)
{
// return `pIndex` (index of the pivot element) int mid = start;
return pIndex; int pivot = nums[end];
}
while (mid <= end)
// Quicksort routine {
public static void quicksort(int[] a, int start, int end) if (nums[mid] < pivot)
{ {
// base condition swap(nums, start,
if (start >= end) { mid);
return; ++start;
} ++mid;
}
// rearrange elements across pivot else if (nums[mid] > pivot)
int pivot = partition(a, start, end); {
swap(nums, mid,
// recur on subarray containing elements less than the end);
pivot --end;
quicksort(a, start, pivot - 1); }
else {
// recur on subarray containing elements more than the ++mid;
pivot }
quicksort(a, pivot + 1, end); }
}
// nums[start … mid-1] contains all
// Java implementation of the Quicksort algorithm occurrences of a pivot
public static void main(String[] args) return new Pair(start - 1, mid);
{ }
int[] a = { 9, -3, 5, 2, 6, 8, -6, 1, 3 };
// 3–way Quicksort routine
quicksort(a, 0, a.length - 1); public static void quicksort(int[] nums, int start, int
end)
// print the sorted array {
System.out.println(Arrays.toString(a)); // base condition for 0 or 1 elements
} if (start >= end) {
} return;
}
QS Dutch
// rearrange elements across pivot using
import java.util.Arrays; the Dutch national flag algorithm
Pair pivot = partition(nums, start, end);
// A simple pair class in Java
class Pair // recur on the subarray containing
{ elements that are less than the pivot
private int x; quicksort(nums, start, pivot.getX());
private int y;
// recur on the subarray containing
Pair(int x, int y) elements that are more than the pivot
{ quicksort(nums, pivot.getY(), end);
this.x = x; }
this.y = y;

4
public static void main(String[] args) // find midpoint
{ int mid = (low + ((high - low) >> 1));
int[] nums = { 2, 6, 5, 2, 6, 8, 6, 1, 2, 6 }; int inversionCount = 0;

// sort list // recursively split runs into two halves


quicksort(nums, 0, nums.length - 1); until run size <= 1,
// then merges them and return up the
// print the sorted array call chain

System.out.println(Arrays.toString(nums)); // split/merge left half


} inversionCount += mergesort(arr, aux,
} low, mid);

Inversion count O(n.log(n)) // split/merge right half


import java.util.Arrays; inversionCount += mergesort(arr, aux,
mid + 1, high);
class Main
{ // merge the two half runs
// Merge two sorted subarrays `arr[low … mid]` inversionCount += merge(arr, aux, low,
and `arr[mid+1 … high]` mid, high);
public static int merge(int[] arr, int[] aux, int low, int
mid, int high) return inversionCount;
{ }
int k = low, i = low, j = mid + 1;
int inversionCount = 0; public static void main(String[] args)
{
// while there are elements in the left and int[] arr = { 1, 9, 6, 4, 5 };
right runs int[] aux = Arrays.copyOf(arr, arr.length);
while (i <= mid && j <= high)
{ // get the inversion count by performing
if (arr[i] <= arr[j]) { merge sort on arr
aux[k++] = arr[i++]; System.out.println("The inversion count
} is " +
else {
aux[k++] = arr[j++]; mergesort(arr, aux, 0, arr.length - 1));
inversionCount += }
(mid - i + 1); // NOTE }
}
}
Segregate positive and negative integers using merge
// copy remaining elements sort O(n.log(n))
while (i <= mid) {
aux[k++] = arr[i++]; import java.util.Arrays;
}
class Main
/* no need to copy the second half {
(since the remaining items // Merge two subarrays, `arr[low… mid]` and
are already in their correct position in `arr[mid+1… high]`,
the temporary array) */ // such that all positive numbers follow negative
numbers
// copy back to the original array to public static void merge(int[] arr, int[] aux, int low,
reflect sorted order int mid, int high)
for (i = low; i <= high; i++) { {
arr[i] = aux[i]; int k = low;
}
// copy negative elements from the left
return inversionCount; subarray
} for (int i = low; i <= mid; i++)
{
// Sort array `arr[low…high]` using auxiliary array if (arr[i] < 0) {
`aux` aux[k++] = arr[i];
public static int mergesort(int[] arr, int[] aux, int low, }
int high) }
{
// base case // copy negative elements from the right
if (high <= low) { // if run subarray
size <= 1 for (int j = mid + 1; j <= high; j++)
return 0; {
} if (arr[j] < 0) {
aux[k++] = arr[j];

5
} {
} private final int x;
private final int y;
// copy positive elements from the left
subarray Pair(int x, int y)
for (int i = low; i <= mid; i++) {
{ this.x = x;
if (arr[i] >= 0) { this.y = y;
aux[k++] = arr[i]; }
}
} public int getX() { return x; }
public int getY() { return y; }
// copy positive elements from the right }
subarray
for (int j = mid + 1; j <= high; j++) class Main
{ {
if (arr[j] >= 0) { public static void swap (int[] arr, int i, int j)
aux[k++] = arr[j]; {
} int temp = arr[i];
} arr[i] = arr[j];
arr[j] = temp;
// copy back to the original array to }
reflect sorted order
for (int i = low; i <= high; i++) { public static int partition(int a[], int start, int end)
arr[i] = aux[i]; {
} // Pick the rightmost element as a pivot
} from the array
int pivot = a[end];
// Segregate positive and negative integers using a
mergesort-like routine // elements less than the pivot will go to
public static void partition(int[] arr, int[] aux, int low, the left of `pIndex`
int high) // elements more than the pivot will go to
{ the right of `pIndex`
// Base case // equal elements can go either way
if (high <= low) { int pIndex = start;
return;
} // each time we find an element less
than or equal to the pivot,
// find midpoint // `pIndex` is incremented, and that
int mid = (low + ((high - low) >> 1)); element would be placed
// before the pivot.
partition(arr, aux, low, mid); for (int i = start; i < end; i++)
// split/merge left half {
partition(arr, aux, mid + 1, high); if (a[i] <= pivot)
// split/merge right half {
swap(a, i, pIndex);
merge(arr, aux, low, mid, high); pIndex++;
// join the two half runs }
} }

public static void main(String[] args) // swap `pIndex` with pivot


{ swap (a, pIndex, end);
int[] arr = { 9, -3, 5, -2, -8, -6, 1, 3 };
int[] aux = Arrays.copyOf(arr, arr.length); // return `pIndex` (index of the pivot
element)
partition(arr, aux, 0, arr.length - 1); return pIndex;
}
System.out.println(Arrays.toString(arr));
} // Iterative Quicksort routine
} public static void iterativeQuicksort(int[] a)
{
// create a stack for storing subarray
start and end index
Stack<Pair> stack = new Stack<>();
Iterative quicksort
import java.util.Arrays; // get the starting and ending index of
import java.util.Stack; the given array
int start = 0;
// A simple pair class in Java int end = a.length - 1;
class Pair

6
// push the start and end index of the // compares it with the target
array into the stack
stack.push(new Pair(start, end)); int mid = (left + right) / 2;

// loop till stack is empty // overflow can happen. Use below


while (!stack.empty()) // int mid = left + (right - left) / 2;
{
// remove top pair from the list // Base condition (a target is found)
and get subarray starting if (target == nums[mid]) {
// and ending indices return mid;
start = stack.peek().getX(); }
end = stack.peek().getY();
stack.pop(); // discard all elements in the right search
space,
// rearrange elements across // including the middle element
pivot else if (target < nums[mid]) {
int pivot = partition(a, start, return binarySearch(nums,
end); left, mid - 1, target);
}
// push subarray indices
containing elements that are // discard all elements in the left search
// less than the current pivot to space,
stack // including the middle element
if (pivot - 1 > start) { else {
stack.push(new return binarySearch(nums,
Pair(start, pivot - 1)); mid + 1, right, target);
} }
}
// push subarray indices
containing elements that are public static void main(String[] args)
// more than the current pivot {
to stack int[] nums = { 2, 5, 6, 8, 9, 10 };
if (pivot + 1 < end) { int target = 5;
stack.push(new
Pair(pivot + 1, end)); int left = 0;
} int right = nums.length - 1;
}
} int index = binarySearch(nums, left,
right, target);
// Iterative Implementation of Quicksort
public static void main(String[] args) if (index != -1) {
{ System.out.println("Element
int a[] = { 9, -3, 5, 2, 6, 8, -6, 1, 3 }; found at index " + index);
}
iterativeQuicksort(a); else {
System.out.println("Element
// print the sorted array not found in the array");
System.out.println(Arrays.toString(a)); }
} }
} }

Binary Search O(log2n) Find the number of rotations in a circularly sorted array
O(log(n))
class Main class Main
{ {
// Recursive implementation of the binary search // Function to find the total number of times the array is
algorithm to return rotated
// the position of `target` in subarray public static int findRotationCount(int[] nums)
nums[left…right] {
public static int binarySearch(int[] nums, int left, int // search space is nums[left…right]
right, int target) int left = 0;
{ int right = nums.length - 1;
// Base condition (search space is
exhausted) // loop till the search space is exhausted
if (left > right) { while (left <= right)
return -1; {
} // if the search space is already sorted, we have
// found the minimum element (at index `left`)
// find the mid-value in the search space if (nums[left] <= nums[right]) {
and return left;

7
} int mid = (left + right) / 2;

int mid = (left + right) / 2; // if the key is found, return its


index
// find the next and previous element of the `mid` if (target == nums[mid]) {
element return mid;
// (in a circular manner) }
int next = (mid + 1) % nums.length;
int prev = (mid - 1 + nums.length) % nums.length; // if right half nums[mid…right]
is sorted and `mid` is not
// if the `mid` element is less than both its next and // the key element
previous if (nums[mid] <= nums[right])
// neighbor, it is the array's minimum element {
// compare key with
if (nums[mid] <= nums[next] && nums[mid] <= nums[mid] and nums[right] to know
nums[prev]) { // if it lies in
return mid; nums[mid…right] or not
} if (target >
nums[mid] && target <= nums[right])
// if nums[mid…right] is sorted, and `mid` is not the {
minimum element, // go
// then the pivot element cannot be present in searching in the right sorted half
nums[mid…right], left = mid
// discard nums[mid…right] and search in the left half + 1;
}
else if (nums[mid] <= nums[right]) { else {
right = mid - 1; right =
} mid - 1; // go searching left
}
// if nums[left…mid] is sorted, then the pivot element }
cannot be present
// in it; discard nums[left…mid] and search in the right // if left half nums[left…mid] is
half sorted, and `mid` is not
// the key element
else if (nums[mid] >= nums[left]) { else {
left = mid + 1; // compare key with
} nums[left] and nums[mid] to know
} // if it lies in
nums[left…mid] or not
// invalid input if (target >=
return -1; nums[left] && target < nums[mid])
} {
// go
public static void main(String[] args) searching in the left sorted half
{ right =
int[] nums = { 8, 9, 10, 1, 2, 3, 4, 5, 6, 7 }; mid - 1;
}
System.out.println("Array is rotated " + else {
findRotationCount(nums) + " times"); left = mid
} + 1; // go searching right
} }
Search an element in a circularly sorted array }
O(log(n)) }
class Main
{ // key not found or invalid input
// Function to find an element in a circularly sorted return -1;
array }
public static int searchCircularArray(int[] nums, int
target) public static void main(String[] args)
{ {
// search space is nums[left…right] int[] nums = {9, 10, 2, 5, 6, 8};
int left = 0; int key = 5;
int right = nums.length - 1;
int index = searchCircularArray(nums,
// loop till the search space is exhausted key);
while (left <= right)
{ if (index != -1) {
// find the mid-value in the System.out.println("Element
search space and found at index " + index);
// compares it with the target }

8
else { System.out.println("The first
System.out.println("Element occurrence of element " + target +
not found in the array");
} " is located at index " + index);
} }
} else {
System.out.println("Element
Find the first of a given number in a sorted array not found in the array");
O(log(n)) }
}
class Main }
{
// Function to find the first occurrence of a given Find the last occurrence of a given number in a sorted
number array
// in a sorted integer array O(log(n))
public static int findFirstOccurrence(int[] nums, int class Main
target) {
{ // Function to find the last occurrence of a given
// search space is nums[left…right] number
int left = 0; // in a sorted integer array
int right = nums.length - 1; public static int findLastOccurrence(int[] nums, int
target)
// initialize the result by -1 {
int result = -1; // search space is nums[left…right]
int left = 0;
// loop till the search space is exhausted int right = nums.length - 1;
while (left <= right)
{ // initialize the result by -1
// find the mid-value in the int result = -1;
search space and compares it with the target
int mid = (left + right) / 2; // loop till the search space is exhausted
while (left <= right)
// if the target is located, {
update the result and // find the mid-value in the
// search towards the left search space and compares it with the target
(lower indices) int mid = (left + right) / 2;
if (target == nums[mid])
{ // if the target is located,
result = mid; update the result and
right = mid - 1; // search towards the right
} (higher indices)
if (target == nums[mid])
// if the target is less than the {
middle element, discard the right half result = mid;
else if (target < nums[mid]) { left = mid + 1;
right = mid - 1; }
}
// if the target is less than the
// if the target is more than the middle element, discard the right half
middle element, discard the left half else if (target < nums[mid]) {
else { right = mid - 1;
left = mid + 1; }
}
} // if the target is more than the
middle element, discard the left half
// return the leftmost index, or -1 if the else {
element is not found left = mid + 1;
return result; }
} }

public static void main(String[] args) // return the leftmost index, or -1 if the
{ element is not found
int[] nums = {2, 5, 5, 5, 6, 6, 8, 9, 9, 9}; return result;
int target = 5; }

int index = findFirstOccurrence(nums, public static void main(String[] args)


target); {
int[] nums = {2, 5, 5, 5, 6, 6, 8, 9, 9, 9};
if (index != -1) int target = 5;
{

9
int index = findLastOccurrence(nums, // if the target is more than the
target); middle element, discard the left half
else {
if (index != -1) left = mid + 1;
{ }
System.out.println("The last }
occurrence of element " + target +
" is // return the found index or -1 if the
located at index " + index); element is not found
} return result;
else { }
System.out.println("Element
not found in the array"); public static void main(String[] args)
} {
} int[] nums = {2, 5, 5, 5, 6, 6, 8, 9, 9, 9};
} int target = 5;

Count occurrences of a number in a sorted array with // pass true for the first occurrence
duplicates int first = binarySearch(nums, target,
O(log(n)) true);
class Main
{ // pass false for the last occurrence
// Function to find the first or last occurrence of a int last = binarySearch(nums, target,
given number in false);
// a sorted integer array. If `searchFirst` is true,
return the int count = last - first + 1;
// first occurrence of the number; otherwise, return
its last occurrence. if (first != -1) {
public static int binarySearch(int[] nums, int target, System.out.println("Element "
boolean searchFirst) + target + " occurs " + count + " times");
{ }
// search space is nums[left…right] else {
int left = 0; System.out.println("Element
int right = nums.length - 1; not found in the array");
}
// initialize the result by -1 }
int result = -1; }

// loop till the search space is exhausted Find the smallest missing element from a sorted array
while (left <= right) O(log(n))
{ class Main
// find the mid-value in the {
search space and compares it with the target // Function to find the smallest missing element in a sorted
int mid = (left + right) / 2; // array of distinct non-negative integers
public static int findSmallestMissing(int[] nums, int left, int
// if the target is found, update right)
the result {
if (target == nums[mid]) // base condition
{ if (left > right) {
result = mid; return left;
}
// go on searching
towards the left (lower indices) int mid = left + (right - left) / 2;
if (searchFirst) {
right = // if the mid-index matches with its value, then the
mid - 1; mismatch
} // lies on the right half
// go on searching if (nums[mid] == mid) {
towards the right (higher indices) return findSmallestMissing(nums, mid + 1, right);
else { }
left = mid else {
+ 1; // mismatch lies on the left half
} return findSmallestMissing(nums, left, mid - 1);
} }
}
// if the target is less than the
middle element, discard the right half public static void main(String[] args)
else if (target < nums[mid]) { {
right = mid - 1; int[] nums = { 0, 1, 2, 3, 4, 5, 6 };
}

10
int left = 0, right = nums.length - 1; public static int findFloor(int[] nums, int left, int
System.out.println("The smallest missing element is " right, int x)
+ findSmallestMissing(nums, left, right)); {
} // search space is nums[left…right]
}
// base case
Find floor and ceil of a number in a sorted integer array if (nums.length == 0) {
O(log(n)) return -1;
class Main }
{
// Function to find the ceiling of `x` in a sorted array // if `x` is less than the lowest element in
nums[low…high]. search
// i.e., the smallest integer greater than or equal to // space, its floor doesn't exist
`x` if (x < nums[left]) {
public static int findCeiling(int[] nums, int left, int return -1;
right, int x) }
{
// search space is nums[left…right] // if `x` is more than equal to the highest
element in
// base case // the search space, it is the floor
if (nums.length == 0) { if (x >= nums[right]) {
return -1; return nums[right];
} }

// if `x` is less than equal to the lowest // find the middle index
element in search int mid = (left + right) / 2;
// space, the lowest element is the
ceiling // this check is placed to handle infinite
if (x <= nums[left]) { loop for
return nums[left]; // a call to `findFloor(nums, mid, right, x)`
} if (mid == left) {
return nums[left];
// if `x` is more than the highest element }
in the search space,
// its ceiling doesn't exist // if `x` is equal to the middle element, it
if (x > nums[right]) { is the floor
return -1; if (nums[mid] == x) {
} return nums[mid];
}
// find the middle index
int mid = (left + right) / 2; // if `x` is more than the middle element,
the floor exists in the right
// if `x` is equal to the middle element, it // subarray nums[mid…right](Note –
is the ceiling middle element can also be the floor)
if (nums[mid] == x) { else if (nums[mid] < x) {
return nums[mid]; return findFloor(nums, mid,
} right, x);
}
// if `x` is more than the middle element,
the ceiling exists in the right // if `x` is less than the middle element,
// subarray nums[mid+1…right] the floor exists in the left
else if (nums[mid] < x) { // subarray nums[left…mid-1]
return findCeiling(nums, mid + else {
1, right, x); return findFloor(nums, left,
} mid - 1, x);
}
// if `x` is less than the middle element, }
the ceiling exists in the left
// subarray nums[left…mid] (Note – public static void main(String[] args)
middle element can also be ceiling) {
else { int[] nums = { 1, 4, 6, 8, 9 };
return findCeiling(nums, left,
mid, x); for (int i = 0; i <= 10; i++)
} {
} System.out.printf("Number
%2d —> ceiling is %2d, floor is %2d\n", i,
// Function to find the floor of `x` in a sorted array
nums[left…right]. findCeiling(nums, 0, nums.length - 1, i),
// i.e., the largest integer less than or equal to `x`
findFloor(nums, 0, nums.length - 1, i));

11
} int target = 5;
}
} int index = searchElement(nums,
target);
Search in a nearly sorted array in logarithmic time
O(log(n)) if (index != -1) {
class Main System.out.println("Element "
{ + target + " found at index " + index);
// Function to search an element `target` in a }
nearly sorted array `nums` else {
public static int searchElement(int[] nums, int System.out.println("Element
target) not found in the array");
{ }
// search space is nums[left…right] }
int left = 0; }
int right = nums.length - 1;
Find the number of 1’s in a sorted binary array
// loop till the search space is exhausted O(log(n))
while (left <= right) class Main
{ {
// find middle index `mid` and // Function to find the total number of 1's in a
compare nums[mid-1], nums[mid], and nums[mid+1] sorted binary array
// with the target number public static int count(int[] nums, int left, int right)
int mid = (left + right) / 2; {
// base case
// return `mid` if the middle if (nums == null || nums.length == 0) {
element is equal to the target number return 0;
if (nums[mid] == target) { }
return mid;
} // if the last array element is 0, no 1's
can
// return `mid-1` if nums[mid-1] // be present since it is sorted
is equal to target number if (nums[right] == 0) {
else if (mid - 1 >= left && return 0;
nums[mid - 1] == target) { }
return mid - 1;
} // if the first array element is 1, all its
elements
// return `mid+1` if // are ones only since it is sorted
nums[mid+1] is equal to target number if (nums[left] == 1) {
else if (mid + 1 <= right && return (right - left + 1);
nums[mid + 1] == target) { }
return mid + 1;
} // divide the array into left and right
subarray and recur
// if the middle element is less int mid = (left + right) / 2;
than the target number, return count(nums, left, mid) +
// reduce search space to the count(nums, mid + 1, right);
right subarray nums[mid+2…right] }
else if (target > nums[mid]) {
left = mid + 2; public static void main(String[] args)
} {
int[] nums = { 0, 0, 0, 0, 1, 1, 1 };
// if the middle element is
greater than the target number, System.out.println("The total number of
// reduce search space to the 1's present is "
right subarray nums[left…mid-2]
else { + count(nums, 0, nums.length
right = mid - 2; - 1));
} }
} }

// invalid input or number is not present Find the peak element in an array
in the array O(log(n))
return -1;
} class Main
{
public static void main(String[] args) // Recursive function to find the peak element in an
{ array
int[] nums = { 2, 1, 3, 5, 4, 7, 6, 8, 9 };

12
public static int findPeakElement(int[] nums, int
left, int right) // Find maximum subarray sum for the
{ left subarray,
// find the middle element. To avoid // including the middle element
overflow, use mid = low + (high - low) / 2 int leftMax = Integer.MIN_VALUE;
int mid = (left + right) / 2; int sum = 0;
for (int i = mid; i >= left; i--)
// check if the middle element is greater {
than its neighbors sum += nums[i];
if ((mid == 0 || nums[mid - 1] <= if (sum > leftMax) {
nums[mid]) && leftMax = sum;
(mid == }
nums.length - 1 || nums[mid + 1] <= nums[mid])) { }
return mid;
} // Find maximum subarray sum for the
right subarray,
// If the left neighbor of `mid` is greater // excluding the middle element
than the middle element, int rightMax = Integer.MIN_VALUE;
// find the peak recursively in the left sum = 0; // reset sum to 0
subarray for (int i = mid + 1; i <= right; i++)
if (mid - 1 >= 0 && nums[mid - 1] > {
nums[mid]) { sum += nums[i];
return findPeakElement(nums, if (sum > rightMax) {
left, mid - 1); rightMax = sum;
} }
}
// If the right neighbor of `mid` is greater
than the middle element, // Recursively find the maximum
// find the peak recursively in the right subarray sum for the left
subarray // and right subarray, and take maximum
return findPeakElement(nums, mid + 1, int maxLeftRight =
right); Integer.max(findMaximumSum(nums, left, mid),
}
findMaximumSum(nums, mid
public static int findPeakElement(int[] nums) + 1, right));
{
// base case // return the maximum of the three
if (nums == null || nums.length == 0) { return Integer.max(maxLeftRight,
System.exit(-1); leftMax + rightMax);
} }

int index = findPeakElement(nums, 0, // Wrapper over findMaximumSum() function


nums.length - 1); public static int findMaximumSum(int[] nums)
return nums[index]; {
} // base case
if (nums == null || nums.length == 0) {
public static void main(String[] args) return 0;
{ }
int[] nums = { 8, 9, 10, 2, 5, 6 };
System.out.println("The peak element is return findMaximumSum(nums, 0,
" + findPeakElement(nums)); nums.length - 1);
} }
}
public static void main(String[] args)
Maximum Subarray Sum using Divide and Conquer {
O(n.log(n)) int[] nums = { 2, -4, 1, 9, -6, 7, -3 };
class Main
{ System.out.println("The maximum sum
// Function to find the maximum subarray sum of the subarray is " +
using divide-and-conquer
public static int findMaximumSum(int[] nums, int findMaximumSum(nums));
left, int right) }
{ }
// If the array contains 0 or 1 element
if (right == left) { Power function Optimized Divide and Conquer Solution
return nums[left]; O(log(n))
} class Main
{
// Find the middle array element // Optimized recursive solution to calculate `pow(x,
int mid = (left + right) / 2; n)`

13
// using divide-and-conquer if (nums[mid] - nums[0] !=
public static long power(int x, int n) (mid - 0) * diff) {
{ right = mid - 1;
// base condition }
if (n == 0) {
return 1L; // if the missing element lies
} on the right subarray, reduce
// our search space to the right
// calculate subproblem recursively subarray nums[mid+1…right]
long pow = power(x, n / 2); else {
left = mid + 1;
if ((n & 1) == 1) { // if `y` is odd }
return x * pow * pow; }
} return -1;
}
// otherwise, `y` is even
return pow * pow; public static void main(String[] args)
} {
int[] nums = { 5, 7, 9, 11, 15 };
public static void main(String[] args)
{ System.out.println("The missing term is "
int x = -2; + findMissingTerm(nums));
int n = 10; }
}
System.out.println("pow(" + x + ", " + n +
") = " + power(x, n)); Find floor and ceil of a number in a sorted array
} (Recursive solution)
} O(log(n))
class Main
Find the missing term in a sequence in logarithmic time {
O(log(n)) // Function to find the ceiling of `x` in a sorted array
class Main nums[low…high].
{ // i.e., the smallest integer greater than or equal to
// Function to find a missing term in a sequence `x`
public static int findMissingTerm(int[] nums) public static int findCeiling(int[] nums, int left, int
{ right, int x)
// search space is nums[left…right] {
int left = 0, right = nums.length - 1; // search space is nums[left…right]

// calculate the common difference // base case


between successive elements if (nums.length == 0) {
int diff = (nums[nums.length - 1] - return -1;
nums[0]) / nums.length; }

// loop till the search space is exhausted // if `x` is less than equal to the lowest
while (left <= right) element in search
{ // space, the lowest element is the
// find the middle index ceiling
int mid = right - (right - left) / 2; if (x <= nums[left]) {
return nums[left];
// check the difference of }
middle element with its right neighbor
if (mid + 1 < nums.length && // if `x` is more than the highest element
nums[mid + 1] - nums[mid] != diff) { in the search space,
return nums[mid + // its ceiling doesn't exist
1] - diff; if (x > nums[right]) {
} return -1;
}
// check the difference of
middle element with its left neighbor // find the middle index
if (mid - 1 >= 0 && nums[mid] int mid = (left + right) / 2;
- nums[mid - 1] != diff) {
return nums[mid - 1] // if `x` is equal to the middle element, it
+ diff; is the ceiling
} if (nums[mid] == x) {
return nums[mid];
// if the missing element lies }
on the left subarray, reduce
// our search space to the right // if `x` is more than the middle element,
subarray nums[left…mid-1] the ceiling exists in the right

14
// subarray nums[mid+1…right] // subarray nums[left…mid-1]
else if (nums[mid] < x) { else {
return findCeiling(nums, mid + return findFloor(nums, left,
1, right, x); mid - 1, x);
} }
}
// if `x` is less than the middle element,
the ceiling exists in the left public static void main(String[] args)
// subarray nums[left…mid] (Note – {
middle element can also be ceiling) int[] nums = { 1, 4, 6, 8, 9 };
else {
return findCeiling(nums, left, for (int i = 0; i <= 10; i++)
mid, x); {
} System.out.printf("Number
} %2d —> ceiling is %2d, floor is %2d\n", i,

// Function to find the floor of `x` in a sorted array findCeiling(nums, 0, nums.length - 1, i),
nums[left…right].
// i.e., the largest integer less than or equal to `x` findFloor(nums, 0, nums.length - 1, i));
public static int findFloor(int[] nums, int left, int }
right, int x) }
{ }
// search space is nums[left…right]
Find the frequency of each element in a sorted array
// base case containing duplicates
if (nums.length == 0) { O(m.log(n))
return -1; m is the total number of distinct element
} import java.util.HashMap;
import java.util.Map;
// if `x` is less than the lowest element in
search class Main
// space, its floor doesn't exist {
if (x < nums[left]) { // Function to find the frequency of each element in
return -1; a sorted array
} public static void findFrequency(int[] nums, int left,
int right,
// if `x` is more than equal to the highest
element in Map<Integer, Integer> freq)
// the search space, it is the floor {
if (x >= nums[right]) { if (left > right) {
return nums[right]; return;
} }

// find the middle index // if every element in subarray


int mid = (left + right) / 2; nums[left…right] is equal,
// then increment the element's count by
// this check is placed to handle infinite `n`
loop for if (nums[left] == nums[right])
// a call to `findFloor(nums, mid, right, x)` {
if (mid == left) { Integer count =
return nums[left]; freq.get(nums[left]);
} if (count == null) {
count = 0;
// if `x` is equal to the middle element, it }
is the floor
if (nums[mid] == x) { freq.put(nums[left], count +
return nums[mid]; (right - left + 1));
} return;
}
// if `x` is more than the middle element,
the floor exists in the right int mid = (left + right)/2;
// subarray nums[mid…right](Note –
middle element can also be the floor) // divide the array into left and right
else if (nums[mid] < x) { subarray and recur
return findFloor(nums, mid, findFrequency(nums, left, mid, freq);
right, x); findFrequency(nums, mid + 1, right,
} freq);
}
// if `x` is less than the middle element,
the floor exists in the left public static void main(String[] args)

15
{
int[] nums = { 2, 2, 2, 4, 4, 4, 5, 5, 6, 8, // return result
8, 9 }; return result;
}
// find the frequency of each array
element and store it in a map public static void main(String[] args)
Map<Integer, Integer> freq = new {
HashMap<>(); for (int i = 0; i <= 16; i++) {
findFrequency(nums, 0, nums.length - 1, System.out.printf("sqrt(%d) =
freq); %d\n", i, sqrt(i));
}
System.out.println(freq); }
} }
}
Division of two numbers using binary search algorithm
Find the square root of a number using a binary search O(log(n))
O(log(x)) class Main
{
class Main // Function to perform a division of two numbers
{ using the
// Function to find the square root of `x` using the // binary search algorithm
binary search algorithm. public static double divide(double x, double y)
// If `x` is not a perfect square, return the floor of {
the square root // handle divisibility by 0
public static int sqrt(int x) if (y == 0) {
{ return Double.MAX_VALUE;
// base case // return INFINITY
if (x < 2) { }
return x;
} // Set range for result [left, right].
// `right` is set to INFINITY to handle the
// to store floor of `sqrt(x)` case
int result = 0; // when `y < 1`, and `x < result <
Double.MAX_VALUE`
// the square root of `x` cannot be more double left = 0.0, right =
than `x/2` for `x > 1` Double.MAX_VALUE;
int start = 1;
int end = x/2; // set accuracy of the result
double precision = 0.001;
while (start <= end)
{ // store sign of the result
// find the middle element int sign = 1;
int mid = (start + end) / 2; if (x * y < 0) {
long sqr = mid*mid; sign = -1;
}
// return `mid` if `x` is a perfect
square // make both input numbers positive
if (sqr == x) { x = Math.abs(x);
return mid; y = Math.abs(y);
}
while (true)
// if `mid×mid` is less than `x` {
else if (sqr < x) // calculate mid
{ double mid = left + ((right -
// discard left search left) / 2);
space
start = mid + 1; // if `y×mid` is almost equal to
`x`, return `mid`
// update result if (Math.abs(y * mid - x) <=
since we need a floor precision) {
result = mid; return mid * sign;
} }

// if `mid×mid` is more than `x` // if `y×mid` is less than `x`,


else { update `left` to `mid`
// discard the right if (y * mid < x) {
search space left = mid;
end = mid - 1; }
} else {
}

16
// if `y×mid` is more int[] nums = { 2, 2, 1, 1, 3, 3, 2, 2, 4, 4,
than `x`, update `right` to `mid` 3, 1, 1 };
right = mid;
} int index = findOddOccuring(nums, 0,
} nums.length - 1);
} System.out.println("The odd occurring
element is " + nums[index]);
public static void main(String[] args) { }
System.out.println(divide(22, 7)); }
}
} Find pairs with difference k in an array Constant Space
Solution
Find the odd occurring element in an array in O(n.log(n)).
logarithmic time import java.util.Arrays;
O(log(n))
class Main class Main
{ {
// Recursive function to find an odd occurring // Function to find a pair with the given difference
element in an array in the array.
// using binary search. This function assumes the // This method handles duplicates in the array
input is valid. public static void findPair(int[] A, int diff)
public static int findOddOccuring(int[] nums, int {
low, int high) // sort array in ascending order
{ Arrays.sort(A);
// base case
if (low == high) { // do for each array element
return low; for (int i = 0; i < A.length; i++)
} {
// to avoid printing duplicates
// find the middle index (skip adjacent duplicates)
int mid = (low + high) / 2; while (i < A.length - 1 && A[i]
== A[i+1]) {
// if `mid` is odd i++;
if (mid % 2 == 1) }
{
// if the element before `mid` is // perform a binary search on
the same as the middle element, the odd element `A[i]-diff`
// element lies on the right if (Arrays.binarySearch(A, A[i]
side; otherwise, it lies on the left side - diff) >= 0) {
if (nums[mid] == nums[mid -
1]) { System.out.println("(" + A[i] + ", " + (A[i] - diff) + ")");
return }
findOddOccuring(nums, mid + 1, high); }
} }
else {
return public static void main(String[] args)
findOddOccuring(nums, low, mid - 1); {
} int[] A = { 1, 5, 2, 2, 2, 5, 5, 4};
} int diff = 3;

// `mid` is even findPair(A, diff);


else { }
// if the element next to `mid` }
is the same as the middle element, the odd
// element lies on the right Find k closest elements to a given value in an array
side; otherwise, it lies on the left side O(n)
if (nums[mid] == nums[mid + import java.util.Arrays;
1]) { import java.util.List;
return import java.util.stream.Collectors;
findOddOccuring(nums, mid + 2, high);
} class Main
else { {
return // Function to find the `k` closest elements to
findOddOccuring(nums, low, mid); `target` in a sorted integer array `nums`
} public static List<Integer>
} findKClosestElements(int[] nums, int k, int target)
} {
int left = 0;
public static void main(String[] args) int right = nums.length - 1;
{

17
while (right - left >= k) if (right - left == 1)
{ // common comparison
if (Math.abs(nums[left] - {
target) > Math.abs(nums[right] - target)) { if (nums[left] < nums[right])
left++; // comparison 1
} {
else { if (p.min >
right--; nums[left]) { // comparison 2
} p.min =
} nums[left];
}
return Arrays.stream(nums, left, right +
1).boxed() if (p.max <
nums[right]) { // comparison 3
.collect(Collectors.toList()); p.max =
} nums[right];
}
public static void main(String[] args) }
{ else {
int[] nums = {10, 12, 15, 17, 18, 20, 25 }; if (p.min >
int target = 16, k = 4; nums[right]) { // comparison 2
p.min =
nums[right];
System.out.println(findKClosestElements(nums, k, target)); }
}
} if (p.max <
nums[left]) { // comparison 3
Find the minimum and maximum element in an array p.max =
using Divide and Conquer nums[left];
O(n) }
// nums Pair class to wrap immutable primitive ints }
class Pair
{ return;
public int max, min; }

public Pair(int max, int min) // find the middle element


{ int mid = (left + right) / 2;
this.max = max;
this.min = min; // recur for the left subarray
} findMinAndMax(nums, left, mid, p);
}
// recur for the right subarray
class Main findMinAndMax(nums, mid + 1, right, p);
{ }
// Divide and conquer solution to find the minimum
and maximum number in an array public static void main(String[] args)
public static void findMinAndMax(int[] nums, int {
left, int right, Pair p) int[] nums = { 7, 2, 9, 3, 1, 6, 7, 8, 4 };
{
// if the array contains only one element // initialize the minimum element by
INFINITY and the
if (left == right) // maximum element by -INFINITY
// common comparison Pair p = new Pair(Integer.MIN_VALUE,
{ Integer.MAX_VALUE);
if (p.max < nums[left]) { findMinAndMax(nums, 0, nums.length -
// comparison 1 1, p);
p.max = nums[left];
} System.out.println("The minimum array
element is " + p.min);
if (p.min > nums[right]) { System.out.println("The maximum array
// comparison 2 element is " + p.max);
p.min = nums[right]; }
} }

return; Longest Common Prefix (LCP) Problem


} O(N.M)
import java.util.Arrays;
// if the array contains only two elements import java.util.List;

class Main

18
{ int data;
// Function to find the longest common prefix Node next;
between two strings
public static String LCP(String X, String Y) public Node(int data)
{ {
int i = 0, j = 0; this.data = data;
while (i < X.length() && j < Y.length()) this.next = null;
{ }
if (X.charAt(i) != Y.charAt(j)) { }
break;
} class Main
{
i++; j++; // Utility function to print contents of a linked list
} public static void printList(Node node)
{
return X.substring(0, i); while (node != null)
} {
System.out.print(node.data + "
// A recursive function to find the longest common —> ");
prefix (LCP) between a node = node.next;
// given set of strings }
public static String findLCP(List<String> words, int System.out.print("null");
low, int high) }
{
// base case: if `low` is more than `high`, // Takes two lists sorted in increasing order and
return an empty string merges their nodes
if (low > high) { // to make one big sorted list returned
return ""; public static Node sortedMerge(Node a, Node b)
} {
// base cases
// base case: if `low` is equal to `high`, if (a == null) {
return the current string return b;
if (low == high) { }
return words.get(low); else if (b == null) {
} return a;
}
// find the mid-index
int mid = (low + high) / 2; Node result;

// partition the problem into subproblems // pick either `a` or `b`, and recur
and recur for each subproblem if (a.data <= b.data)
String X = findLCP(words, low, mid); {
String Y = findLCP(words, mid + 1, result = a;
high); result.next =
sortedMerge(a.next, b);
// return the longest common prefix of }
strings `X` and `Y` else {
return LCP(X, Y); result = b;
} result.next = sortedMerge(a,
b.next);
public static void main(String[] args) }
{
List<String> words = return result;
Arrays.asList("techie delight", "tech", "techie", }

// The main function to merge given `k` sorted


"technology", "technical"); linked lists.
// It takes array `lists` of size `k` and generates the
System.out.println("The longest sorted output
common prefix is " + public static Node mergeKLists(Node[] lists)
{
findLCP(words, 0, words.size() - 1)); // base case
} if (lists == null || lists.length == 0) {
} return null;
}
Efficiently merge k sorted linked lists
O(n.log(k)) int last = lists.length - 1;
// A Linked List Node
class Node // repeat until only one list is left
{ while (last != 0)

19
{ class Main
int i = 0, j = last; {
// Helper function to print a given linked list
// `(i, j)` forms a pair public static void printList(Node head)
while (i < j) {
{ Node ptr = head;
// merge list `j` with while (ptr != null)
`i` {
lists[i] = System.out.print(ptr.data + "
sortedMerge(lists[i], lists[j]); —> ");
ptr = ptr.next;
// consider the next }
pair
i++; System.out.println("null");
j--; }

// if all pairs are // Takes two lists sorted in increasing order and
merged, update last merge their nodes
if (i >= j) { // to make one big sorted list, which is returned
last = j; public static Node sortedMerge(Node a, Node b)
} {
} // base cases
} if (a == null) {
return b;
return lists[0]; }
} else if (b == null) {
return a;
public static void main(String[] s) }
{
int k = 3; // total number of linked lists Node result;

// an array to store the head nodes of // pick either `a` or `b`, and recur
the linked lists if (a.data <= b.data)
Node[] lists = new Node[k]; {
result = a;
lists[0] = new Node(1); result.next =
lists[0].next = new Node(5); sortedMerge(a.next, b);
lists[0].next.next = new Node(7); }
else {
lists[1] = new Node(2); result = b;
lists[1].next = new Node(3); result.next = sortedMerge(a,
lists[1].next.next = new Node(6); b.next);
lists[1].next.next.next = new Node(9); }

lists[2] = new Node(4); return result;


lists[2].next = new Node(8); }
lists[2].next.next = new Node(10);
/*
// Merge all lists into one Split the given list's nodes into front and
Node head = mergeKLists(lists); back halves,
If the length is odd, the extra node
printList(head); should go in the front list.
} It uses the fast/slow pointer strategy
} */
public static Node[] frontBackSplit(Node source)
Merge sort algorithm for a singly linked list {
O(n.log(n)) // if the length is less than 2, handle it
// A Linked List Node separately
class Node if (source == null || source.next == null) {
{ return new Node[]{ source,
int data; null };
Node next; }

Node(int data, Node next) Node slow = source;


{ Node fast = source.next;
this.data = data;
this.next = next; // advance `fast` two nodes, and
} advance `slow` one node
} while (fast != null)
{

20
fast = fast.next;
if (fast != null) class Main
{ {
slow = slow.next; // Utility function to push a node at the beginning of
fast = fast.next; the doubly linked list
} public static Node push(Node head, int key)
} {
Node node = new Node(key);
// `slow` is before the midpoint in the list, node.next = head;
so split it in two
// at that point. // change `prev` of the existing head
Node[] arr = new Node[]{ source, node to point to the new node
slow.next }; if (head != null) {
slow.next = null; head.prev = node;
}
return arr;
} // return new head node
return node;
// Sort a given linked list using the merge sort }
algorithm
public static Node mergesort(Node head) // Helper function to print nodes of a doubly linked
{ list
// base case — length 0 or 1 public static void printDDL(Node head)
if (head == null || head.next == null) { {
return head; while (head != null)
} {
System.out.print(head.data + "
// split `head` into `a` and `b` sublists ⇔ ");
Node[] arr = frontBackSplit(head); head = head.next;
Node front = arr[0]; }
Node back = arr[1];
System.out.println("null");
// recursively sort the sublists }
front = mergesort(front);
back = mergesort(back); // Function to split nodes of the given doubly linked
list into
// answer = merge the two sorted lists // two halves using the fast/slow pointer strategy
return sortedMerge(front, back); public static Node split(Node head)
} {
Node slow = head;
public static void main(String[] args) Node fast = head.next;
{
// input keys // advance `fast` by two nodes, and
int[] keys = { 8, 6, 4, 9, 3, 1 }; advance `slow` by a single node
while (fast != null)
Node head = null; {
for (int key: keys) { fast = fast.next;
head = new Node(key, head); if (fast != null)
} {
slow = slow.next;
// sort the list fast = fast.next;
head = mergesort(head); }
}
// print the sorted list
printList(head); return slow;
} }
}
// Recursive function to merge nodes of two sorted
Sort a doubly-linked list using merge sort lists
O(n.log(n)) // into a single sorted list
// A Doubly Linked List Node public static Node merge(Node a, Node b)
class Node {
{ // base cases
int data; if (a == null) {
Node next, prev; return b;
}
Node(int data) {
this.data = data; if (b == null) {
} return a;
} }

21
num = Math.abs(num);
// pick either `a` or `b`, and recur
if (a.data <= b.data) // drop last bit from num (divide it by 2)
{ int i = num >> 1;
a.next = merge(a.next, b);
a.next.prev = a; // if num is odd
a.prev = null; if ((num & 1) == 1) {
return a; return ((findSquare(i) << 2) +
} (i << 2) + 1);
else { }
b.next = merge(a, b.next); // if num is even
b.next.prev = b; else {
b.prev = null; return (findSquare(i) << 2);
return b; }
} }
}
public static void main(String[] args) {
// Function to sort a doubly-linked list using merge System.out.print(findSquare(8));
sort algorithm }
public static Node mergesort(Node head) }
{
// base case: 0 or 1 node
if (head == null || head.next == null) {
return head;
}

// split head into `a` and `b` sublists


Node a = head, b;

Node slow = split(head);


b = slow.next;
slow.next = null;

// recursively sort the sublists


a = mergesort(a);
b = mergesort(b);

// merge the two sorted lists


head = merge(a, b);
return head;
}

public static void main(String[] args)


{
int[] keys = { 6, 4, 8, 7, 9, 2, 1 };

Node head = null;


for (int key: keys) {
head = push(head, key);
}

head = mergesort(head);
printDDL(head);
}
}

Find the square of a number without using the


multiplication and division operator

class Main
{
public static int findSquare(int num)
{
// base case
if (num < 2) {
return num;
}

// convert the number to positive if it is


negative

22

You might also like