Arrays COPY Flashcards

1
Q

Location of the next index depends on the data type that we use
True/false

A

true

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Advantages of using arrays:

A

Arrays allow random access of elements. This makes accessing elements by their position faster.
Arrays have better cache locality that can make a pretty big difference in performance.

Programs with good locality tend to access the same set of data items over and over again from the upper levels of the memory hierarchy (i.e. cache) and thus run faster.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Time Complexity of this search operation in an array will be

A

O(N) in the worst case as we are checking every element of the array from 1st to last, so the number of operations is N.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Time complexity of insertion in an array ?

A

Time Complexity in worst case of this insertion operation can be linear i.e. O(N) as we might have to shift all of the elements by one place to the right.

O(1) for insertion at the end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

what is sliding window technique

A

This technique shows how a nested for loop in few problems can be converted to single for loop and hence reducing the time complexity.

Let’s start with a problem for illustration where we can apply this technique:
Given an array of integers of size ‘n’.
Our aim is to calculate the maximum sum of ‘k’
consecutive elements in the array.

Input : arr[] = {100, 200, 300, 400}
k = 2
Output : 700

Input : arr[] = {1, 4, 2, 10, 23, 3, 1, 0, 20}
k = 4
Output : 39
We get maximum sum by adding subarray {4, 2, 10, 23}
of size 4.

Input  : arr[] = {2, 3}
         k = 3
Output : Invalid
There is no subarray of size 3 as size of whole
array is 2.

The Naive Approach to solve this problem is to calculate sum for each of the blocks of K consecutive elements and compare which block has the maximum sum possible. The time complexity of this approach will be O(n * k).

The above problem can be solved in Linear Time Complexity by using Window Sliding Technique by avoiding the overhead of calculating sum repeatedly for each block of k elements.

The technique can be best understood with the window pane in bus, consider a window of length n and the pane which is fixed in it of length k. Consider, initially the pane is at extreme left i.e., at 0 units from the left. Now, co-relate the window with array arr[] of size n and plane with current_sum of size k elements. Now, if we apply force on the window such that it moves a unit distance ahead. The pane will cover next k consecutive elements.

Consider an array arr[] = {5 , 2 , -1 , 0 , 3} and value of k = 3 and n = 5

Applying sliding window technique :
We compute the sum of first k elements out of n terms using a linear loop and store the sum in variable window_sum.
Then we will graze linearly over the array till it reaches the end and simultaneously keep track of maximum sum.
To get the current sum of block of k elements just subtract the first element from the previous block and add the last element of the current block .

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is prefix sum array?

A

Prefix Sum Array: The prefix sum array of any array, arr[] is defined as an array of same size say, prefixSum[] such that the value at any index i in prefixSum[] is sum of all elements from indexes 0 to i in arr[].
That is,
prefixSum[i] = arr[0] + arr[1] + arr[2] + . . . . + arr[i]

for all 0 <= i <= N.

Examples:
Input : arr[] = {10, 20, 10, 5, 15}
Output : prefixSum[] = {10, 30, 40, 45, 60}

Explanation : While traversing the array, update
the element by adding it with its previous element.
prefixSum[0] = 10,
prefixSum[1] = prefixSum[0] + arr[1] = 30,
prefixSum[2] = prefixSum[1] + arr[2] = 40 and so on.

void fillPrefixSum(int arr[], int N, int prefixSum[]) 
{ 
    prefixSum[0] = arr[0]; 
    // Adding present element  
    // with previous element 
    for (int i = 1; i < N; i++) 
        prefixSum[i] = prefixSum[i-1] + arr[i]; 
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Reverse an array using recursion

A
import java.util.Arrays;

class GfG {
    
    // recursive function to reverse an array from l to r
    static void reverseArrayRec(int[] arr, int l, int r) {
        if (l >= r)
            return;
  
        // Swap the elements at the ends
        int temp = arr[l];
        arr[l] = arr[r];
        arr[r] = temp;
  
        // Recur for the remaining array
        reverseArrayRec(arr, l + 1, r - 1);
    }

    // function to reverse an array
    static void reverseArray(int[] arr) {
        int n = arr.length;
        reverseArrayRec(arr, 0, n - 1);
    }

    public static void main(String[] args) {
        int[] arr = { 1, 4, 3, 2, 6, 5 };

        reverseArray(arr);
  
        for (int i = 0; i < arr.length; i++) 
            System.out.print(arr[i] + " ");
    }
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

brute force

Maximum and minimum of an array using minimum number of comparisons

A
import java.util.Arrays;

public class MinMaxFinder {

    /**
     * Finds the minimum element in an array of integers.
     *
     * @param A The input array.
     * @param N The size of the array.
     * @return The minimum element in the array.
     */
    public static int setmini(int[] A, int N)
    {
        int mini = Integer.MAX_VALUE;
        for (int i = 0; i < N; i++) {
            if (A[i] < mini) {
                mini = A[i];
            }
        }
        return mini;
    }

    /**
     * Finds the maximum element in an array of integers.
     *
     * @param A The input array.
     * @param N The size of the array.
     * @return The maximum element in the array.
     */
    public static int setmaxi(int[] A, int N)
    {
        int maxi = Integer.MIN_VALUE;

        for (int i = 0; i < N; i++) {
            if (A[i] > maxi) {
                maxi = A[i];
            }
        }
        return maxi;
    }

    public static void main(String[] args)
    {
        int[] A = { 4, 9, 6, 5, 2, 3 };
        int N = A.length;
        System.out.println("Minimum element is: "
                           \+ setmini(A, N));
        System.out.println("Maximum element is: "
                           \+ setmaxi(A, N));
    }
}

Time Complexity: O(N)

Auxiliary Space: O(1)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Do by brute force: Given an array and a number k where k is smaller than the size of the array, we need to find the k’th smallest element in the given array. It is given that all array elements are distinct.

Examples:

Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 3
Output: 7

Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 4
Output: 10

A

Method 1 (Simple Solution)
A simple solution is to sort the given array using an O(N log N) sorting algorithm like Merge Sort, Heap Sort, etc, and return the element at index k-1 in the sorted array.
Time Complexity of this solution is O(N Log N)

// Function to return k'th smallest element in a given array
int kthSmallest(int arr[], int n, int k)
{
    // Sort the given array
    sort(arr, arr + n);
    // Return k'th element in the sorted array
    return arr[k - 1];
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q
Given an array of size N containing only 0s, 1s, and 2s; sort the array in ascending order.
Example 1:
Input: 
N = 5
arr[]= {0 2 1 2 0}
Output:
0 0 1 2 2
Explanation:
0s 1s and 2s are segregated 
into ascending order.
Example 2:
Input: 
N = 3
arr[] = {0 1 0}
Output:
0 0 1
Explanation:
0s 1s and 2s are segregated 
into ascending order.
Your Task:You don't need to read input or print anything. Your task is to complete the function sort012() that takes an array arr and N as input parameters and sorts the array in-place.
Expected Time Complexity: O(N)Expected Auxiliary Space: O(1)
Constraints:1 <= N <= 10^60 <= A[i] <= 2
A
Approach:The problem is similar to our old post Segregate 0s and 1s in an array, and both of these problems are variation of famous Dutch national flag problem.The problem was posed with three colours, here `0′, `1′ and `2′. The array is divided into four sections:
* a[1..Lo-1] zeroes (red)
* a[Lo..Mid-1] ones (white)
* a[Mid..Hi] unknown
* a[Hi+1..N] twos (blue)
* If the ith element is 0 then swap the element to the low range, thus shrinking the unknown range.
* Similarly, if the element is 1 then keep it as it is but shrink the unknown range.
* If the element is 2 then swap it with an element in high range.
Algorithm:
* Keep three indices low = 1, mid = 1 and high = N and there are four ranges, 
1 to low (the range containing 0), 
low to mid (the range containing 1), 
mid to high (the range containing unknown elements) 
and high to N (the range containing 2).
* Traverse the array from start to end and mid is less than high. (Loop counter is i)
* If the element is 0 then swap the element with the element at index low and update low = low + 1 and mid = mid + 1
* If the element is 1 then update mid = mid + 1
* If the element is 2 then swap the element with the element at index high and update high = high – 1 and update i = i – 1. 
As the swapped element is not processed
* Print the array.
// C++ program to sort an array with 0, 1 and 2 in a single pass
#include (bits/stdc++.h>
using namespace std;
// Function to sort the input array, the array is assumed to have values in {0, 1, 2}
void sort012(int a[], int arr_size){
int lo = 0;
int hi = arr_size - 1;
int mid = 0;
// Iterate till all the elements are sorted
while (mid (= hi) {
switch (a[mid]) {
// If the element is 0
case 0: swap(a[lo++], a[mid++]); 
break;
// If the element is 1 .
case 1: mid++; 
break;
// If the element is 2
case 2: swap(a[mid], a[hi--]); 
break;
}
}
}
// Function to print array 
arr[]void printArray(
int arr[], int arr_size){
// Iterate and print every element
for (int i = 0; i ( arr_size; i++)
cout (( arr[i] (( " ";
}
// Driver Code
int main(){
int arr[] = { 0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
sort012(arr, n);
cout (( "array after segregation ";
printArray(arr, n);
return 0;}

Complexity Analysis:
Time Complexity: O(n).Only one traversal of the array is needed.
Space Complexity: O(1).No extra space is required.

Another approach-
Count the number of 0s, 1s and 2s in the given array. Then store all the 0s in the beginning followed by all the 1s then all the 2s.
Algorithm:
* Keep three counter c0 to count 0s, c1 to count 1s and c2 to count 2s
* Traverse through the array and increase the count of c0 if the element is 0,increase the count of c1 if the element is 1 and increase the count of c2 if the element is 2
* Now again traverse the array and replace first c0 elements with 0, next c1 elements with 1 and next c2 elements with 2.
Implementation:
// C++ implementation of the approach
#include (bits/stdc++.h>
using namespace std;
// Utility function to print the contents of an array
void printArr(int arr[], int n){
for (int i = 0; i ( n; i++)
cout (( arr[i] (( " ";
}
// Function to sort the array of 0s, 1s and 2s
void sortArr(int arr[], int n){
int i, cnt0 = 0, cnt1 = 0, cnt2 = 0;
// Count the number of 0s, 1s and 2s in the array
for (i = 0; i ( n; i++) {
switch (arr[i]) {
case 0: cnt0++; 
break;
case 1: cnt1++; 
break;
case 2: cnt2++; 
break;
}
}
// Update the array
i = 0;
// Store all the 0s in the beginning
while (cnt0 > 0) {
arr[i++] = 0;
cnt0--;
}
// Then all the 1s
while (cnt1 > 0) {
arr[i++] = 1;
cnt1--;
}
// Finally all the 2s
while (cnt2 > 0) {
arr[i++] = 2;
cnt2--;
}
// Print the sorted array
printArr(arr, n);
}
// Driver code
int main(){
int arr[] = { 0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1 };
int n = sizeof(arr) / sizeof(int);
sortArr(arr, n);
return 0;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Move all negative numbers to beginning and positive to end with constant extra space

A

Approach: We can solve this problem using the partision approach used in quick sort.
The process mimics quicksort’s partitioning:

Iterate Through the Array:

Loop through all elements of the array, checking if they satisfy <= 0.
Partitioning Based on Condition:

When an element satisfies <= 0:
Move it to the “left group” by swapping it with the element at position j (pointer tracking the boundary between the groups).
Increment j to expand the boundary of the left group.
Result After Partition:

At the end of the loop:
All elements before index j are non-positive (<= 0).
All elements after index j are positive (> 0).

public static void main(String[] args) {
		int[] input = {-1, 2, -3, 1, 1};

		move(input);
        for (int j : input) {
            System.out.print(j + " ");
        }
	}

	private static void move(int[] input) {
		int j = 0;
		int temp;
		for (int i = 0; i < input.length; i++) {
			if (input[i] <= 0) {
				if (i != j) {
					temp = input[i];
					input[i] = input[j];
					input[j] = temp;
				}
				j++;
			}
		}
	}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
Given two arrays a[]and b[]of size nand m respectively. The task is to find union between these two arrays.
Union of the two arrays can be defined as the set containing distinct elements from both the arrays. If there are repetitions, then only one occurrence of element should be printed in the union.
Example 1:
Input:
5 3
1 2 3 4 5
1 2 3
Output: 
5
Explanation: 
1, 2, 3, 4 and 5 are the
elements which comes in the union set
of both arrays. So count is 5.
Example 2:
Input:
6 2 
85 25 1 32 54 6
85 2 
Output: 
7
Explanation: 
85, 25, 1, 32, 54, 6, and
2 are the elements which comes in the
union set of both arrays. So count is 7.

Your Task:
Complete doUnion funciton that takes a, n, b, m as parameters and returns the count of union elements of thetwo arrays. The printing is done by the driver code.
Constraints:1 ≤ n, m≤ 1050 ≤ a[i], b[i] 5

Expected Time Complexity : O((n+m)log(n+m))
Expected Auxilliary Space : O(n+m)

A
int doUnion(int a[], int n, int b[], int m) {   
set s;   
s.insert(a, a+n);   
s.insert(b, b+m);   
return s.size(); 
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Largest Sum Contiguous Subarray

A
Using kadane's algorithm
// C++ program to print largest contiguous array sum
#include(iostream>
#include(climits>
using namespace std;
int maxSubArraySum(int a[], int size){
int max_so_far = INT_MIN, max_ending_here = 0;
for (int i = 0; i ( size; i++){
max_ending_here = max_ending_here + a[i];
if (max_so_far ( max_ending_here) 
max_so_far = max_ending_here;
if (max_ending_here ( 0) 
max_ending_here = 0;
}
return max_so_far;
}
/*Driver program to test maxSubArraySum*/
int main(){
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int n = sizeof(a)/sizeof(a[0]);
int max_sum = maxSubArraySum(a, n);
cout (( "Maximum contiguous sum is " (( max_sum;
return 0;
}
Another approach-
#include(iostream>
using namespace std;
int maxSubArraySum(int a[], int size){
int max_so_far = a[0];
int curr_max = a[0];
for (int i = 1; i ( size; i++){
curr_max = max(a[i], curr_max+a[i]);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
/* Driver program to test maxSubArraySum */
int main(){
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int n = sizeof(a)/sizeof(a[0]);
int max_sum = maxSubArraySum(a, n);
cout (( "Maximum contiguous sum is " (( max_sum;
return 0;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Given an array arr[], the task is to find the elements of a contiguous subarray of numbers which has the largest sum.
Examples:
Input: arr = [-2, -3, 4, -1, -2, 1, 5, -3]
Output: [4, -1, -2, 1, 5]
Explanation:In the above input the maximum contiguous subarray sum is 7 and the elements of the subarray are [4, -1, -2, 1, 5]
Input: arr = [-2, -5, 6, -2, -3, 1, 5, -6]
Output: [6, -2, -3, 1, 5]
Explanation:In the above input the maximum contiguous subarray sum is 7 and the elementsof the subarray are [6, -2, -3, 1, 5]

A

Naive Approach: The naive approach is to generate all the possible subarray and print that subarray which has maximum sum.
Time complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: The idea is to use the Kadane’s Algorithm to find the maximum subarray sum and store the starting and ending index of the subarray having maximum sum and print the subarray from starting index to ending index.

Below are the steps:

Initialize 3 variables endIndex to 0, currMax and globalMax to first value of the input array.
For each element in the array starting from index(say i) 1, update currMax to max(nums[i], nums[i] + currMax) and globalMax and endIndex to i only if currMax > globalMax.

To find the start index, iterate from endIndex in the left direction and keep decrementing the value of globalMax until it becomes 0. The point at which it becomes 0 is the start index.
Now print the subarray between [start, end].

Below is the implementation of the above approach:
// C++ program for the above approach
#include (bits/stdc++.h>
using namespace std;
// Function to print the elements of Subarray with maximum sum
void SubarrayWithMaxSum(vector(int>& nums){
// Initialize currMax and globalMax with first value of nums
int endIndex; 
int currMax = nums[0];
int globalMax = nums[0];
// Iterate for all the elements of the array
for (int i = 1; i < nums.size(); ++i) {
// Update currMax
currMax = max(nums[i],nums[i] + currMax);
// Check if currMax is greater than
globalMax
if (currMax > globalMax) { 
globalMax = currMax; 
endIndex = i;
}
}
int startIndex = endIndex;
// Traverse in left direction to find start Index of subarray
while (startIndex >= 0) {
globalMax -= nums[startIndex];
if (globalMax == 0) break;
// Decrement the start index
startIndex--;
}
// Printing the elements of subarray with max sum
for (int i = startIndex;i (= endIndex; ++i) {
cout << nums[i] << " ";
}
}
// Driver Codeint main(){
// Given array arr[]
vector(int> arr= { -2, -5, 6, -2, -3, 1, 5, -6 };
// Function callSubarrayWithMaxSum(arr);
return 0;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Kadane’s algorithm

A

Initialize:
max_so_far = INT_MIN
max_ending_here = 0
Loop for each element of the array
(a) max_ending_here = max_ending_here + a[i]
(b) if(max_so_far < max_ending_here) max_so_far = max_ending_here
(c) if(max_ending_here < 0) max_ending_here = 0
return max_so_far

Explanation:The simple idea of Kadane’s algorithm is to look for all positive contiguous segments of the array (max_ending_here is used for this). And keep track of maximum sum contiguous segment among all positive segments (max_so_far is used for this). Each time we get a positive-sum compare it with max_so_far and update max_so_far if it is greater than max_so_far

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Find peak element in a sorted array

Given an array of integers. Find a peak element in it. An array element is a peak if it is NOT smaller than its neighbours. For corner elements, we need to consider only one neighbour.

Example:

Input: array[]= {5, 10, 20, 15}
Output: 20
The element 20 has neighbours 10 and 15,
both of them are less than 20.

Input: array[] = {10, 20, 15, 2, 23, 90, 67}
Output: 20 or 90
The element 20 has neighbours 10 and 15,
both of them are less than 20, similarly 90 has neighbours 23 and 67.
Following corner cases give better idea about the problem.

If input array is sorted in strictly increasing order, the last element is always a peak element. For example, 50 is peak element in {10, 20, 30, 40, 50}.
If the input array is sorted in strictly decreasing order, the first element is always a peak element. 100 is the peak element in {100, 80, 60, 50, 20}.
If all elements of input array are same, every element is a peak element.

A

It is clear from the above examples that there is always a peak element in the input array.

Naive Approach: The array can be traversed and the element whose neighbours are less than that element can be returned.
Algorithm:

If in the array, the first element is greater than the second or the last element is greater than the second last, print the respective element and terminate the program.
Else traverse the array from the second index to the second last index
If for an element array[i], it is greater than both its neighbours, i.e., array[i] > array[i-1] and array[i] > array[i+1], then print that element and terminate.

// A C++ program to find a peak element
#include (bits/stdc++.h>
using namespace std;
// Find the peak element in the array
int findPeak(int arr[], int n)
{
	// first or last element is peak element
	if (n == 1)
	return 0;
	if (arr[0] >= arr[1])
		return 0;
	if (arr[n - 1] >= arr[n - 2])
		return n - 1;
	// check for every other element
	for (int i = 1; i ( n - 1; i++) {
		// check if the neighbors are smaller
		if (arr[i] >= arr[i - 1] && arr[i] >= arr[i + 1])
			return i;
	}
}
// Driver Code
int main()
{
	int arr[] = { 1, 3, 20, 4, 1, 0 };
	int n = sizeof(arr) / sizeof(arr[0]);
	cout (( "Index of a peak point is "
		(( findPeak(arr, n);
	return 0;
}

Output:

Index of a peak point is 2
Complexity Analysis:

Time complexity: O(n).
One traversal is needed so the time complexity is O(n)
Space Complexity: O(1).
No extra space is needed, so space complexity is constant
Efficient Approach: Divide and Conquer can be used to find a peak in O(Logn) time. The idea is based on the technique of Binary Search to check if the middle element is the peak element or not. If the middle element is not the peak element, then check if the element on the right side is greater than the middle element then there is always a peak element on the right side. If the element on the left side is greater than the middle element then there is always a peak element on the left side. Form a recursion and the peak element can be found in log n time.

Algorithm:

Create two variables, l and r, initialize l = 0 and r = n-1
Iterate the steps below till l <= r, lowerbound is less than the upperbound
Check if the mid value or index mid = (l+r)/2, is the peak element or not, if yes then print the element and terminate.
Else if the element on the left side of the middle element is greater then check for peak element on the left side, i.e. update r = mid – 1
Else if the element on the right side of the middle element is greater then check for peak element on the right side, i.e. update l = mid + 1

// A C++ program to find a peak element
// using divide and conquer
#include (bits/stdc++.h>
using namespace std;
// A binary search based function
// that returns index of a peak element
int findPeakUtil(int arr[], int low,
				int high, int n)
{
	// Find index of middle element
	// (low + high)/2
	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 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 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()
int findPeak(int arr[], int n)
{
	return findPeakUtil(arr, 0, n - 1, n);
}
// Driver Code
int main()
{
	int arr[] = { 1, 3, 20, 4, 1, 0 };
	int n = sizeof(arr) / sizeof(arr[0]);
	cout (( "Index of a peak point is "
		(( findPeak(arr, n);
	return 0;
}
Output: 

Index of a peak point is 2
Complexity Analysis:

Time Complexity: O(Logn).
Where n is the number of elements in the input array. In each step our search becomes half. So it can be compared to Binary search, So the time complexity is O(log n)
Space complexity: O(1).
No extra space is required, so the space complexity is constant.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Minimize the maximum difference between the heights

Given heights of n towers and a value k. We need to either increase or decrease the height of every tower by k (only once) where k > 0. The task is to minimize the difference between the heights of the longest and the shortest tower after modifications and output this difference.
Examples:

Input  : arr[] = {1, 15, 10}, k = 6
Output :  Maximum difference is 5.
Explanation : We change 1 to 7, 15 to 
9 and 10 to 4. Maximum difference is 5
(between 4 and 9). We can't get a lower
difference.

Input : arr[] = {1, 5, 15, 10}
k = 3
Output : Maximum difference is 8
arr[] = {4, 8, 12, 7}

Input : arr[] = {4, 6}
k = 10
Output : Maximum difference is 2
arr[] = {14, 16} OR {-6, -4}

Input : arr[] = {6, 10}
k = 3
Output : Maximum difference is 2
arr[] = {9, 7}

Input : arr[] = {1, 10, 14, 14, 14, 15}
k = 6
Output: Maximum difference is 5
arr[] = {7, 4, 8, 8, 8, 9}

Input : arr[] = {1, 2, 3}
k = 2
Output: Maximum difference is 2
arr[] = {3, 4, 5}

A

First, we try to sort the array and make each height of the tower maximum. We do this by decreasing the height of all the towers towards the right by k and increasing all the height of the towers towards the left (by k). It is also possible that the tower you are trying to increase the height doesn’t have the maximum height. Therefore we only need to check whether it has the maximum height or not by comparing it with the last element towards the right side which is a[n]-k. Since the array is sorted if the tower’s height is greater than the a[n]-k then it’s the tallest tower available. Similar reasoning can also be applied for finding the shortest tower.

Note:- We need not consider where a[i]
using namespace std;

// User function Template
int getMinDiff(int arr[], int n, int k)
{
sort(arr, arr + n);
int ans = arr[n - 1] - arr[0]; // Maximum possible height difference

int tempmin, tempmax;
tempmin = arr[0];
tempmax = arr[n - 1];

for (int i = 1; i ( n; i++) {
tempmin= min(arr[0] + k,arr[i] - k); // Minimum element when we add k to whole array

tempmax = max(arr[i - 1] + k, arr[n - 1] - k); // Maximum element when we subtract k from whole array
ans = min(ans, tempmax - tempmin);
}
return ans;
}
// Driver Code Starts
int main()
{
	int k = 6, n = 6;
	int arr[n] = { 7, 4, 8, 8, 8, 9 };
	int ans = getMinDiff(arr, n, k);
	cout (( ans;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

solve by naive approach

Jump Game – Minimum Jumps to Reach End

Given an array arr[] of non-negative integers. Each array element represents the maximum length of the jumps that can be made forward from that element. This means if arr[i] = x, then we can jump any distance y such that y ≤ x. Find the minimum number of jumps to reach the end of the array starting from the first element. If an element is 0, then we cannot move through that element.

Note: Return -1 if we can’t reach the end of the array.

Examples:

Input: arr[] = [1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9]
Output: 3 (1-> 3 -> 9 -> 9)
Explanation: Jump from 1st element to 2nd element as there is only 1 step.
Now there are three options 5, 8 or 9. If 8 or 9 is chosen then the end node 9 can be reached. So 3 jumps are made.

Input: arr[] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Output: 10
Explanation: In every step a jump is needed so the count of jumps is 10.

A

Method 1: Naive Recursive Approach.

Using Recursion – O(n^n) Time and O(n) Space

Start from the first element and recursively call for all the elements reachable from the first element. The minimum number of jumps to reach end from first can be calculated using the minimum value from the recursive calls.

minJumps(start) = 1 + Min(minJumps(k)) for all k reachable from start.

// Java program to find the minimum number
// of jumps to reach the end of the array

import java.util.Arrays;

class GfG {

    static int minJumpsRecur(int i, int[] arr) {
        
        // Return 0 when last element is reached.
        if (i >= arr.length - 1)
            return 0;

        // Traverse through all the points
        // reachable from arr[i].
        // Recursively, get the minimum number
        // of jumps needed to reach array end from
        // these points.
        int ans = Integer.MAX_VALUE;
        for (int j = i + 1; j <= i + arr[i]; j++) {
            int val = minJumpsRecur(j, arr);
            if (val != Integer.MAX_VALUE)
                ans = Math.min(ans, 1 + val);
        }

        return ans;
    }

    static int minJumps(int[] arr) {

        int ans = minJumpsRecur(0, arr);
        
        // If end cannot be reached.
        if (ans == Integer.MAX_VALUE) 
            return -1;
            
        return ans;
    }

    public static void main(String[] args) {
        int[] arr = { 1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9 };
        System.out.println(minJumps(arr));
    }
}
19
Q

Given an array of integers nums containingn + 1 integers where each integer is in the range [1, n] inclusive.
There is only one repeated number in nums, return thisrepeatednumber.
You must solve the problem without modifying the array numsand uses only constant extra space.

Example 1:
Input: nums = [1,3,4,2,2]
Output: 2
Example 2:
Input: nums = [3,1,3,4,2]
Output: 3

Constraints:
1 <= n <= 105
* nums.length == n + 11 <= nums[i] <= nAll the integers in nums appear only once except for precisely one integer which appears two or more times.

A

APPROACH-1: NAIVE APPROACH (Brute Force)As we are guranteed that- there’s exactly one duplicate value, so if we compare each element with all the other values and if we see they are equal at any point then we can simply return that.
TC: O(N^2), as we have nested loop here that are running close to N times in both the loopsSC: O(1), as we aren’t using any scaling DS here
CODE:
//NOTE: This one may give you ‘Time Limit Exceeded’ error, as it is not an optimized approachint findDuplicate(vector(int>& nums) { for(int i=0; i(nums.size(); i++){ for(int j=0; j(nums.size() && j!=i; j++){ if(nums[i]==nums[j]){ return nums[i]; } } } return -1; //this one will be executed only when there will be no solution}APPROACH-2: USING SETAs we can check the duplicity of any value in set using O(1) TC only, we’ll use that advantage here. What we’ll do is- we’ll store all the values one by one if it hasn’t been inserted before in the set, and if we see the value already exist there, we can return that value.
TC: O(N), as we are traversing the elements only onceSC: O(N), as in the worst case we may have to store (N-1) values in the set
CODE:
int findDuplicate(vector(int>& nums){ unordered_set(int> s; for(int i=0; i(nums.size(); i++){ if(s.find(nums[i])!=s.end()){ return nums[i]; } s.insert(nums[i]); } return -1;}APPROACH-3: USING FLOYD’S LOOP DETECTION TECHNIQUEThe idea is pretty simple. As we are assured that there will be only one duplicate value, so if we create a virtual Linked List here (see, how we did that->Dry run if you don’t get the idea), and apply the Floyd’s Loop Detection technique here, then we gonna surely face a collision somewhere, and that tells us- yes, we have a duplicate value here. But, in order to find out which value is the duplicate one- we have to set a pointer to the 0-th element and we’ll move both the pointers at a same speed (one step at a time). Whenever we’ll see the ‘slow’ and ‘fast’ are having equal values that will be the duplicate value.
NOTE: If you didn’t get the idea make sure you know Floyd’s Loop Detection Algorithm (in Linked List), and also dry run the below code.
TC: almost O(N), because it may require us to have more than N opertaions to find out the collisionSC: O(1), as there’s no scaling DS used
CODE:
int findDuplicate(vector(int>& nums){ int slow=nums[0], fast=nums[0]; //NOTE: We are using do-while loop here, because at the very first step ‘fast==slow’. you can use normal while loop also, but for that you have to add additional conditions also. do{ slow=nums[slow]; //one step at a time fast=nums[nums[fast]]; //two steps at a time }while(slow!=fast); //We have met our first collision, now we have to find out the value for which the collision happened slow=nums[0]; //re-initializing the slow pointer with the 0-th value while(slow!=fast){ slow=nums[slow]; //one step at a time fast=nums[fast]; //one step at a time } return fast; //return slow will also work }

20
Q

d

A
21
Q

Merge intervals
Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.
Example 1:
Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
Example 2:
Input: intervals = [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considered overlapping.

Constraints:
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104

A

The idea is to sort the intervals by their starting points. Then, we take the first interval and compare its end with the next intervals starts. As long as they overlap, we update the end to be the max end of the overlapping intervals. Once we find a non overlapping interval, we can add the previous “extended” interval and start over.

Sorting takes O(n log(n)) and merging the intervals takes O(n). So, the resulting algorithm takes O(n log(n)).

I used a lambda comparator (Java 8) and a for-each loop to try to keep the code clean and simple.

class Solution {
	public int[][] merge(int[][] intervals) {
		if (intervals.length <= 1)
			return intervals;

		// Sort by ascending starting point
		Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));

		List<int[]> result = new ArrayList<>();
		int[] newInterval = intervals[0];
		result.add(newInterval);
		for (int[] interval : intervals) {
			if (interval[0] <= newInterval[1]) // Overlapping intervals, move the end if needed
				newInterval[1] = Math.max(newInterval[1], interval[1]);
			else {                             // Disjoint intervals, add the new interval to the list
				newInterval = interval;
				result.add(newInterval);
			}
		}

		return result.toArray(new int[result.size()][]);
	}
}
22
Q

31. Next Permutation

A permutation of an array of integers is an arrangement of its members into a sequence or linear order.

For example, for arr = [1,2,3], the following are all the permutations of arr: [1,2,3], [1,3,2], [2, 1, 3], [2, 3, 1], [3,1,2], [3,2,1].
The next permutation of an array of integers is the next lexicographically greater permutation of its integer. More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, then the next permutation of that array is the permutation that follows it in the sorted container. If such arrangement is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in ascending order).

For example, the next permutation of arr = [1,2,3] is [1,3,2].
Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
While the next permutation of arr = [3,2,1] is [1,2,3] because [3,2,1] does not have a lexicographical larger rearrangement.
Given an array of integers nums, find the next permutation of nums.

The replacement must be in place and use only constant extra memory.

Example 1:

Input: nums = [1,2,3]
Output: [1,3,2]
Example 2:

Input: nums = [3,2,1]
Output: [1,2,3]
Example 3:

Input: nums = [1,1,5]
Output: [1,5,1]

Constraints:

1 <= nums.length <= 100
0 <= nums[i] <= 100

A
23
Q

Count inversion in an array

A

Inversion Count for an array indicates – how far (or close) the array is from being sorted. If the array is already sorted, then the inversion count is 0, but if the array is sorted in the reverse order, the inversion count is the maximum.Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j
Example:
Input: arr[] = {8, 4, 2, 1}
Output: 6
Explanation: Given array has six inversions:(8, 4), (4, 2), (8, 2), (8, 1), (4, 1), (2, 1).
Input: arr[] = {3, 1, 2}
Output: 2
Explanation: Given array has two inversions:(3, 1), (3, 2)
METHOD 1 (Simple)
Approach: Traverse through the array, and for every index, find the number of smaller elements on its right side of the array. This can be done using a nested loop. Sum up the counts for all index in the array and print the sum.
Algorithm:Traverse through the array from start to end For every element, find the count of elements smaller than the current number up to that index using another loop. Sum up the count of inversion for every index. Print the count of inversions.
Implementation:
// C++ program to Count Inversions in an array
#include (bits/stdc++.h>
using namespace std;
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 Code
int main(){int arr[] = { 1, 20, 6, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
cout (( “ Number of inversions are “(( getInvCount(arr, n);
return 0;
}
Complexity Analysis:
Time Complexity: O(n^2), Two nested loops are needed to traverse the array from start to end, so the Time complexity is O(n^2)Space Complexity:O(1), No extra space is required.

METHOD 2(Enhance Merge Sort)
Approach:Suppose the number of inversions in the left half and right half of the array (let be inv1 and inv2); what kinds of inversions are not accounted for in Inv1 + Inv2?
The answer is – the inversions that need to be counted during the merge step. Therefore, to get the total number of inversions that needs to be added are the number of inversions in the left subarray, right subarray, and merge().
How to get the number of inversions in merge()?In merge process, let i is used for indexing left sub-array and j for right sub-array. At any step in merge(), if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j]

Algorithm:
* The idea is similar to merge sort, divide the array into two equal or almost equal halves in each step until the base case is reached.
* Create a function merge that counts the number of inversions when two halves of the array are merged, create two indices i and j, i is the index for the first half, and j is an index of the second half. if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j].
* Create a recursive function to divide the array into halves and find the answer by summing the number of inversions is the first half, the number of inversion in the second half and the number of inversions by merging the two.
* The base case of recursion is when there is only one element in the given half.
* Print
the
answer
Implementation:
#include(bits/stdc++.h>
using namespace std;
long long merge(int arr[], int l, int mid, int r) {
long long inv = 0;
int n1 = mid - l +1;
int n2 = r - (mid + 1) + 1;
int a[n1];
int b[n2];
for (int i=0; i(n1; i++) { 
a[i] = arr[l+i];
}
for (int i=0; i(n2; i++) { 
b[i] = arr[mid +i +l];
}
int i=0, j=0, k=l;
while (i(n1 and j(n2) { 
if (a[i] ( b[j]) {  
arr[k] = a[i];  
k++;  
i++; 
}else {  
arr[k] = b[j];  
inv = n1 - i;  
k++;  
j++; 
}
}
while (i(n1) { 
arr[k] = a[i]; 
k++; 
i++;
}
while (j(n2) { 
arr[k] = b[j]; 
k++; 
j++;
}
return inv;
}
long long mergeSort(int arr[], int l, int r) {
long long inv = 0;
if (l(r) { 
int mid = (l+r)/2; 
inv += mergeSort(arr, l, mid); 
inv += mergeSort(arr, mid + l, r); 
inv += merge(arr, l, mid, r);
}
return inv;
}
int main() {
int n; cin >> n;
int arr[n];
for (int i = 0; i(n; i++) { 
cin>> arr[i];
}
cout (( mergeSort(arr, 0, n-1);
return 0;
}
24
Q

Best time to buy and sell stocks

A
Approach 1: Brute Force
public class Solution { 
public int maxProfit(int prices[]) {   
    int maxprofit = 0;   
    for (int i = 0; i < prices.length - 1; i++) {     
        for (int j = i + 1; j < prices.length; j++) {        
            int profit = prices[j] - prices[i];       
            if (profit > maxprofit)         
            maxprofit = profit;     
         }   
}   
return maxprofit; 
}
}
Complexity Analysis
Time complexity : O(n^2)O(n2).
Space complexity : O(1)O(1). Only two variables
Approach 2: One Pass
public class Solution { 
public 
int maxProfit(int prices[]) {   
    int minprice = Integer.MAX_VALUE;   
    int maxprofit = 0;   
    for (int i = 0; i < prices.length; i++) {     
    if (prices[i] < minprice)       
    minprice = prices[i];     
    else if (prices[i] - minprice > maxprofit)       
   maxprofit = prices[i] - minprice;   
    }   
return maxprofit; 
}
}
Complexity Analysis
Time complexity : O(n)O(n). Only a single pass is needed.
Space complexity : O(1)O(1). Only two variables are used.
25
Q

Best

A
26
Q

Find common elements in three sorted arrays

A
27
Q
  1. Rearrange Array Elements by Sign

You are given a0-indexedinteger arraynumsofevenlength consisting of anequalnumber of positive and negative integers.

You should return the array of nums such that the the array follows the given conditions:

Everyconsecutive pairof integers haveopposite signs.For all integers with the same sign, theorderin which they were present innumsispreserved.The rearranged array begins with a positive integer.

Returnthe modified array after rearranging the elements to satisfy the aforementioned conditions.

Example 1:

Input: nums = [3,1,-2,-5,2,-4] Output: [3,-2,1,-5,2,-4] Explanation: The positive integers in nums are [3,1,2]. The negative integers are [-2,-5,-4]. The only possible way to rearrange them such that they satisfy all conditions is [3,-2,1,-5,2,-4]. Other ways such as [1,-2,2,-5,3,-4], [3,1,2,-2,-5,-4], [-2,3,-5,1,-4,2] are incorrect because they do not satisfy one or more conditions.

Example 2:

Input: nums = [-1,1] Output: [1,-1] Explanation: 1 is the only positive integer and -1 the only negative integer in nums. So nums is rearranged to [1,-1].

Constraints:

2 <= nums.length <= 2 * 105nums.lengthiseven1 <= |nums[i]| <= 105numsconsists ofequalnumber of positive and negative integers.

It is not required to do the modifications in-place.

A
28
Q

Factorial of a large number

A
// Java program to find large
// factorials using BigInteger
import java.math.BigInteger;
import java.util.Scanner;

public class Example {

    // Returns Factorial of N
    static BigInteger factorial(int N)
    {
        // Initialize result
        BigInteger f
            = new BigInteger("1"); // Or BigInteger.ONE

        // Multiply f with 2, 3, ...N
        for (int i = 2; i <= N; i++)
            f = f.multiply(BigInteger.valueOf(i));

        return f;
    }

    // Driver method
    public static void main(String args[]) throws Exception
    {
        int N = 20;
        System.out.println(factorial(N));
    }
}
29
Q

Maximum subarray product

A
long long  currentproduct=1;
    long long maxproduct1=INT_MIN;
    long long maxproduct2=INT_MIN;
    for(int i=0;i(n;i++){
        if(n==1){
            maxproduct1=arr[i];
            break;
        }
        currentproduct=currentproduct*arr[i];
        maxproduct1=max(maxproduct1,currentproduct);
        if(currentproduct==0){
            currentproduct=1;
        }
    }
    currentproduct=1;
    for(int i=n-1;i>0;i--){
        currentproduct=currentproduct*arr[i];
        maxproduct2=max(maxproduct2,currentproduct);
        if(currentproduct==0){
            currentproduct=1;
        }
    }
    return max(maxproduct1,maxproduct2);
30
Q

Given an array of integers, find the length of the longest sub-sequence such that elements in the subsequence are consecutive integers, the consecutive numbers can be in any order.

Examples:

Input: arr[] = {1, 9, 3, 10, 4, 20, 2}
Output: 4
Explanation: 
The subsequence 1, 3, 4, 2 is the longest 
subsequence of consecutive elements

Input: arr[] = {36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42}
Output: 5
Explanation:
The subsequence 36, 35, 33, 34, 32 is the longest
subsequence of consecutive elements.

A

Naive Approach: The idea is to first sort the array and find the longest subarray with consecutive elements.
After sorting the array and removing the multiple occurrences of elements, run a loop and keep a count and max (both initially zero). Run a loop from start to end and if the current element is not equal to the previous (element+1) then set the count to 1 else increase the count. Update max with a maximum of count and max.

// C++ program to find longest
// contiguous subsequence
#include (bits/stdc++.h>
using namespace std;
// Returns length of the longest
// contiguous subsequence
int findLongestConseqSubseq(int arr[], int n)
{
	int ans = 0, count = 0;
	// sort the array
	sort(arr, arr + n);
vector(int> v;
v.push_back(arr[0]);
	//insert repeated elements only once in the vector
	for (int i = 1; i ( n; i++)
	{
		if (arr[i] != arr[i - 1])
			v.push_back(arr[i]);
	}
	// find the maximum length
	// by traversing the array
	for (int i = 0; i ( v.size(); i++)
	{
		// Check if the current element is equal
		// to previous element +1
		if (i > 0 && v[i] == v[i - 1] + 1)
			count++;
		// reset the count
		else
			count = 1;
		// update the maximum
		ans = max(ans, count);
	}
	return ans;
}
// Driver code
int main()
{
	int arr[] = { 1, 2, 2, 3 };
	int n = sizeof arr / sizeof arr[0];
	cout (( "Length of the Longest contiguous subsequence "
			"is "
		(( findLongestConseqSubseq(arr, n);
	return 0;
}

Output
Length of the Longest contiguous subsequence is 3
Complexity Analysis:

Time complexity: O(nLogn).
Time to sort the array is O(nlogn).
Auxiliary space : O(1).
As no extra space is needed.

Efficient solution:
This problem can be solved in O(n) time using an Efficient Solution. The idea is to use Hashing. We first insert all elements in a Set. Then check all the possible starts of consecutive subsequences.

Algorithm:

Create an empty hash.
Insert all array elements to hash.
Do following for every element arr[i]
Check if this element is the starting point of a subsequence. To check this, simply look for arr[i] – 1 in the hash, if not found, then this is the first element a subsequence.
If this element is the first element, then count the number of elements in the consecutive starting with this element. Iterate from arr[i] + 1 till the last element that can be found.
If the count is more than the previous longest subsequence found, then update this.

31
Q

Given an array arr[] of size N and an element k. The task is to find all elements in array that appear more than n/k times.
Example 1:
Input:N = 8arr[] = {3,1,2,2,1,2,3,3}k = 4Output: 2Explanation: In the given array, 3 and2 are the only elements that appearsmore than n/k times.Example 2:
Input:N = 4arr[] = {2,3,3,2}k = 3Output: 2Explanation: In the given array, 3 and 2are the only elements that appears morethan n/k times. So the count of elementsare 2.Your Task:The task is to complete the function countOccurence() which returns count of elements with more than n/k times appearance.
Expected Time Complexity: O(N).Expected Auxiliary Space: O(N).
Constraints:1 <= N <= 1041 <= a[i] <= 1061 <= k <= N

A
int countOccurence(int arr[], int n, int k) {   unordered_map m;   int ans=0;   for (int i=0; i(n; i++) m[arr[i]]++;     if (m[arr[i]]==n/k + 1) {       ans++;     }   }   return ans; }
without using map solution=
    int countOccurence(int arr[], int n, int k) {   // Your code here   int t=n/k,count=1, res=0;   sort(arr,arr+n);   for(int i=0;i(n;i++) {     if(arr[i]==arr[i+1]){       count++;     }     else if(count>t){       counts++;       count=1;     }     else{count=1;}   }   return res; }
32
Q

Maximum profit by buying and selling a share atmost twice

A
33
Q

Given two arrays: a1[0..n-1] of size n and a2[0..m-1] of size m. Task is to check whether a2[] is a subset of a1[] or not. Both the arrays can be sorted or unsorted. It may be assumed that elements in both array are distinct.
Example 1:
Input:a1[] = {11, 1, 13, 21, 3, 7}a2[] = {11, 3, 7, 1}Output:YesExplanation:a2[] is a subset of a1[]
Example 2:
Input:a1[] = {1, 2, 3, 4, 5, 6}a2[] = {1, 2, 4}Output:YesExplanation:a2[] is a subset of a1[]
Example 3:
Input:a1[] = {10, 5, 2, 23, 19}a2[] = {19, 5, 3}Output:NoExplanation:a2[] is not a subset of a1[]
Your Task: You don’t need to read input or print anything. Your task is to complete the function isSubset() which takes the array a1[], a2[], its size n and m as inputs and return “Yes” if arr2 is subset of arr1 else return “No” if arr2 is not subset of arr1.

Expected Time Complexity: O(n)Expected Auxiliary Space: O(n)
Constraints:1 <= n,m <= 1051 <= a1[i], a2[j] <= 105

A
Naive approach:
bool isSubset(int arr1[], int arr2[],      int m, int n){ int i = 0; int j = 0; for (i = 0; i ( n; i++) {   for (j = 0; j ( m; j++) {     if (arr2[i] == arr1[j])       break;   }
   /* If the above inner loop was   not broken at all then arr2[i]   is not present in arr1[] */   if (j == m)     return 0; }
 /* If we reach here then all elements of arr2[] are present in arr1[] */ return 1;}
// Driver codeint main(){ int arr1[] = { 11, 1, 13, 21, 3, 7 }; int arr2[] = { 11, 3, 7, 1 };
 int m = sizeof(arr1) / sizeof(arr1[0]); int n = sizeof(arr2) / sizeof(arr2[0]);
 if (isSubset(arr1, arr2, m, n))   printf("arr2[] is subset of arr1[] "); else   printf("arr2[] is not a subset of arr1[]");
 getchar(); return 0;}
Efficient solution:
string isSubset(int a1[], int a2[], int n, int m) { unordered_set s1; unordered_set s2;  for (int i=0; i   s1.insert(a1[i]); } for (int i=0; i   s2.insert(a2[i]); } for (int i=0; i   if (s1.find(a2[i]) == s1.end()) {     return "No";   } } return "Yes";}
34
Q
Triplet sum in Array
Given an array arr of size n and an integer X. Find if there's a triplet in the array which sums up to the given integer X.
Example 1:
Input:
n = 6, X = 13
arr[] = [1 4 45 6 10 8]
Output:
1
Explanation:
The triplet {1, 4, 8} in 
the array sums up to 13.
Example 2:
Input:
n = 5, X = 10
arr[] = [1 2 4 3 6]
Output:
1
Explanation:
The triplet {1, 3, 6} in 
the array sums up to 10.
Your Task:You don't need to read input or print anything. Your task is to complete the functionfind3Numbers()which takes the array arr[], the size of the array (n) and the sum (X) as inputs and returns True if there exists a triplet in the array arr[] which sums up to X and False otherwise.
Expected Time Complexity:O(n2)Expected Auxiliary Space:O(1)
Constraints:1 ≤ n ≤ 1031 ≤ A[i] ≤ 105
A

Method 1: This is the naive approach towards solving the above problem.

Approach: A simple method is to generate all possible triplets and compare the sum of every triplet with the given value. The following code implements this simple method using three nested loops.

Algorithm:
Given an array of length n and a sum s
* Create three nested loop first loop runs from start to end (loop counter i), second loop runs from i+1 to end (loop counter j) and third loop runs from j+1 to end (loop counter k)
* The counter of these loops represents the index of 3 elements of the triplets.
* Find the sum of ith, jth and kth element. If the sum is equal to given sum. Print the triplet and break.
* If there is no triplet, then print that no triplet exist.
Implementation:

bool find3Numbers(int A[], int arr_size, int sum){ 
int l, r; // Fix the first element as A[i] 
for (int i = 0; i ( arr_size - 2; i++){   
// Fix the second element as A[j]   
for (int j = i + 1; j ( arr_size - 1; j++)   {     
// Now look for the third number     
for (int k = j + 1; k ( arr_size; k++){       
if (A[i] + A[j] + A[k] == sum){
cout (( "Triplet is " (( A[i] ((", " (( A[j] (( ", " (( A[k];      return true;       
}     
}   
} 
}
Complexity Analysis:
Time Complexity: O(n3).There are three nested loops traversing the array, so the time complexity is O(n^3)
Space Complexity: O(1).As no extra space is required.

Method 2: This method uses sorting to increase the efficiency of the code.

Approach: By Sorting the array the efficiency of the algorithm can be improved. This efficient approach uses the two-pointer technique. Traverse the array and fix the first element of the triplet. Now use the Two Pointers algorithm to find if there is a pair whose sum is equal to x – array[i]. Two pointers algorithm take linear time so it is better than a nested loop.

Algorithm :

  • Sort the given array.
  • Loop over the array and fix the first element of the possible triplet, arr[i].Then fix two pointers, one at i + 1 and the other at n – 1. And look at the sum,
  • If the sum is smaller than the required sum, increment the first pointer.
  • Else, If the sum is bigger, Decrease the end pointer to reduce the sum.
  • Else, if the sum of elements at two-pointer is equal to given sum then print the triplet and break.

Implementation:

bool find3Numbers(int A[], int arr_size, int sum){ 
int l, r; /* Sort the elements */ 
sort(A, A + arr_size); 
/* Now fix the first element one by one and find the   other two elements */ 
for (int i = 0; i ( arr_size - 2; i++) {   
// To find the other two elements, start two index   // variables from two corners of the array and move   
// them toward each other   
l = i + 1; // index of the first element in the   
// remaining elements   
r = arr_size - 1; // index of the last element 
while (l ( r) {     
if (A[i] + A[l] + A[r] == sum) {       
printf("Triplet is %d, %d, %d", A[i],A[l], A[r]);       return true;     
}     
else if (A[i] + A[l] + A[r] ( sum)       
l++;     
else // A[i] + A[l] + A[r] > sum       
r--;   
} 
} // If we reach here, then no triplet was found return false;
}
Complexity Analysis:
Time complexity: O(N^2).There are only two nested loops traversing the array, so time complexity is O(n^2). Two pointers algorithm takes O(n) time and the first element can be fixed using another nested traversal.

Space Complexity: O(1).As no extra space is required.

Method 3: This is a Hashing-based solution.
Approach: This approach uses extra space but is simpler than the two-pointers approach. Run two loops outer loop from start to end and inner loop from i+1 to end. Create a hashmap or set to store the elements in between i+1 to j-1. So if the given sum is x, check if there is a number in the set which is equal to x – arr[i] – arr[j]. If yes print the triplet.

Algorithm:Traverse the array from start to end. (loop counter i)Create a HashMap or set to store unique pairs.
Run another loop from i+1 to end of the array. (loop counter j)If there is an element in the set which is equal to x- arr[i] – arr[j], then print the triplet (arr[i], arr[j], x-arr[i]-arr[j]) and break
Insert the jth element in the set.

Implementation:
bool find3Numbers(int A[], int arr_size, int sum){ 
// Fix the first element as A[i] for (int i = 0; i < arr_size - 2; i++) {   
// Find pair in subarray A[i+1..n-1]
// with sum equal to sum - A[i]   
unordered_set s;   
int curr_sum = sum - A[i];   
for (int j = i + 1; j < arr_size; j++){     
if (s.find(curr_sum - A[j]) != s.end()){
printf("Triplet is %d, %d, %d", A[i],A[j], curr_sum - A[j]);       
return true;     
}     
s.insert(A[j]);
} 
} 
// If we reach here, then no triplet was found return false;}/* Driver program to test above function */int main(){ int A[] = { 1, 4, 45, 6, 10, 8 }; int sum = 22; int arr_size = sizeof(A) / sizeof(A[0]); find3Numbers(A, arr_size, sum); return 0;}
35
Q
Given an array arr[]of N non-negative integers representing the height of blocks. Ifwidth of each block is 1, compute how much water can be trappedbetween the blocks during the rainy season.
Example 1:
Input:
N = 6
arr[] = {3,0,0,2,0,4}
Output:
10
A

Basic Insight:An element of the array can store water if there are higher bars on the left and right. The amount of water to be stored in every element can be found out by finding the heights of bars on the left and right sides. The idea is to compute the amount of water that can be stored in every element of the array.
Method 1 : This is a simple solution to the above problem.
Approach: The idea is to traverse every array element and find the highest bars on the left and right sides. Take the smaller of two heights. The difference between the smaller height and height of the current element is the amount of water that can be stored in this array element.Algorithm:
* Traverse the array from start to end.For every element, traverse the array from start to that index and find the maximum height (a) and traverse the array from the current index to end, and find the maximum height (b).The amount of water that will be stored in this column is min(a,b) – array[i], add this value to the total amount of water stored
* Print the total amount of water stored.Implementation:// C++ implementation of the approach#include(bits/stdc++.h>using namespace std;
// Function to return the maximum// water that can be storedint maxWater(int arr[], int n){// To store the maximum water// that can be storedint res = 0;// For every element of the arrayfor (int i = 1; i ( n-1; i++) {// Find the maximum element on its leftint left = arr[i];for (int j=0; j(i; j++)left = max(left, arr[j]);// Find the maximum element on its rightint right = arr[i];for (int j=i+1; j(n; j++)right = max(right, arr[j]);// Update the maximum waterres = res + (min(left, right) - arr[i]);}
return res;}
// Driver codeint main(){int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};int n = sizeof(arr)/sizeof(arr[0]);cout (( maxWater(arr, n);return 0;}Complexity Analysis:
Time Complexity: O(n2).There are two nested loops traversing the array, So time Complexity is O(n2).Space Complexity: O(1).No extra space is required.Another approach-
Instead of maintaining two arrays of size n for storing the left and a right max of each element, maintain two variables to store the maximum till that point. Since water trapped at any element = min(max_left, max_right) – arr[i]. Calculate water trapped on smaller elements out of A[lo] and A[hi] first and move the pointers till lo doesn’t cross hi.
Implementation:// C++ program to find maximum amount of water that can// be trapped within given set of bars.// Space Complexity : O(1)
#include using namespace std;
int findWater(int arr[], int n){// initialize outputint result = 0;
// maximum element on left and rightint left_max = 0, right_max = 0;
// indices to traverse the arrayint lo = 0, hi = n - 1;
while (lo <= hi) {if (arr[lo] < arr[hi]) { if (arr[lo] > left_max) // update max in left left_max = arr[lo]; else // water on curr element = max - curr result += left_max - arr[lo]; lo++;}else { if (arr[hi] > right_max) // update right maximum right_max = arr[hi]; else result += right_max - arr[hi]; hi–;}}
return result;}
int main(){int arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };int n = sizeof(arr) / sizeof(arr[0]);cout &laquo_space;“Maximum water that can be accumulated is “&laquo_space;findWater(arr, n);}
// This code is contributed by Aditi Sharma

36
Q

Given an array A[ ] of positive integers of size N, where each value represents the number of chocolates in a packet. Each packet can have a variable number of chocolates. There are M students, the task is to distribute chocolate packets among M students such that :

  1. Each student gets exactly one packet.
  2. The difference between maximum number of chocolates given to a student and minimum number of chocolates given to a student is minimum.
    Example 1:

Input:
N = 8, M = 5
A = {3, 4, 1, 9, 56, 7, 9, 12}

Output: 6
Explanation: The minimum difference betweenmaximum chocolates and minimum chocolatesis 9 - 3 = 6 by choosing following M packets :{3, 4, 9, 7, 9}.

Example 2:
Input:
N = 7, M = 3
A = {7, 3, 2, 4, 9, 12, 56}
Output: 2
Explanation: The minimum difference between maximum chocolates and minimum chocolates is 4 - 2 = 2 by choosing following M packets :{3, 2, 4}.

Your Task:
You don’t need to take any input or print anything. Your task is to complete the function findMinDiff() which takes array A[ ], N and M as input parameters and returns the minimum possible difference between maximum number of chocolates given to a student and minimum number of chocolates given to a student.
Expected Time Complexity: O(N*Log(N))Expected Auxiliary Space: O(1)
Constraints:1 ≤ T ≤ 1001 ≤ N ≤ 1051 ≤ Ai ≤ 1091 ≤ M ≤ N

A

A simple solution is to generate all subsets of size m of arr[0..n-1]. For every subset, find the difference between the maximum and minimum elements in it. Finally, return the minimum difference.
An efficient solution is based on the observation that to minimize the difference, we must choose consecutive elements from a sorted packet. We first sort the array arr[0..n-1], then find the subarray of size m with the minimum difference between the last and first elements.
// C++ program to solve chocolate distribution problem
#include (bits/stdc++.h>
using namespace std;

// arr[0..n-1] represents sizes of packets m is number of students.
// Returns minimum difference between maximum and minimum values of distribution.
int findMinDiff(int arr[], int n, int m) {
// if there are no chocolates or number of students is 0
if (m == 0 || n == 0) return 0;
// Sort the given packets
sort(arr, arr + n);
// Number of students cannot be more than number of packets
if (n < m) return -1;
// Largest number of chocolates
int min_diff = INT_MAX;

// Find the subarray of size m such that difference between last (maximum in case of sorted) and first (minimum in case of sorted) elements of subarray is minimum.

for (int i = 0; i + m - 1 ( n; i++) {
int diff = arr[i + m - 1] - arr[i];
if (diff ( min_diff)
min_diff = diff;
}
return min_diff;
}
int main()
{
	int arr[] = { 12, 4, 7, 9, 2, 23, 25, 41, 30,
				40, 28, 42, 30, 44, 48, 43, 50 };
	int m = 7; // Number of students
	int n = sizeof(arr) / sizeof(arr[0]);
	cout (( "Minimum difference is "
		(( findMinDiff(arr, n, m);
	return 0;
}
Output
Minimum difference is 10
Time Complexity: O(n Log n) as we apply sorting before subarray search.
Another approach
sort(a.begin(),a.end());   
long long i=0,j=m-1,sum=INT_MAX;   
while(j(n)     
sum=min(a[j++]-a[i++],sum);     
return sum;
37
Q

Smallest subarray with sum greater than a given value
Given an array of integers and a number x, find the smallest subarray with sum greater than the given value.
Examples:arr[] = {1, 4, 45, 6, 0, 19} x = 51Output: 3Minimum length subarray is {4, 45, 6}
arr[] = {1, 10, 5, 2, 7} x = 9Output: 1Minimum length subarray is {10}
arr[] = {1, 11, 100, 1, 0, 200, 3, 2, 1, 250} x = 280Output: 4Minimum length subarray is {100, 1, 0, 200}

A
A simple solution is to use two nested loops. The outer loop picks a starting element, the inner loop considers all elements (on right side of current start) as ending element. Whenever sum of elements between current start and end becomes more than the given number, update the result if current length is smaller than the smallest length so far.
Following is the implementation of simple approach.
# include (iostream>using namespace std;
// Returns length of smallest subarray with sum greater than x.// If there is no subarray with given sum, then returns n+1int smallestSubWithSum(int arr[], int n, int x){ // Initialize length of smallest subarray as n+1  int min_len = n + 1;
  // Pick every element as starting point  for (int start=0; start(n; start++)  {    // Initialize sum starting with current start    int curr_sum = arr[start];
    // If first element itself is greater    if (curr_sum > x) return 1;
    // Try different ending points for current start    for (int end=start+1; end(n; end++)    {      // add last element to current sum      curr_sum += arr[end];
      // If sum becomes more than x and length of      // this subarray is smaller than current smallest      // length, update the smallest length (or result)      if (curr_sum > x && (end - start + 1) ( min_len)        min_len = (end - start + 1);    }  }  return min_len;}
/* Driver program to test above function */int main(){ int arr1[] = {1, 4, 45, 6, 10, 19}; int x = 51; int n1 = sizeof(arr1)/sizeof(arr1[0]); int res1 = smallestSubWithSum(arr1, n1, x); (res1 == n1+1)? cout (( "Not possible\n" :         cout (( res1 (( endl;
Time Complexity: Time complexity of the above approach is clearly O(n2).
Efficient Solution: This problem can be solved in O(n) time using the idea used in this post.
// O(n) solution for finding smallest subarray with sum// greater than x#include (iostream>using namespace std;
// Returns length of smallest subarray with sum greater than// x. If there is no subarray with given sum, then returns// n+1int smallestSubWithSum(int arr[], int n, int x){ // Initialize current sum and minimum length int curr_sum = 0, min_len = n + 1;
 // Initialize starting and ending indexes int start = 0, end = 0; while (end ( n) {   // Keep adding array elements while current sum   // is smaller than or equal to x   while (curr_sum (= x && end ( n)     curr_sum += arr[end++];
   // If current sum becomes greater than x.   while (curr_sum > x && start ( n) {     // Update minimum length if needed     if (end - start ( min_len)       min_len = end - start;
     // remove starting elements     curr_sum -= arr[start++];   } } return min_len;}
38
Q

Three way partitioning of an array around a given range
Given an array and a range [lowVal, highVal], partition the array around the range such that array is divided in three parts.1) All elements smaller than lowVal come first.2) All elements in range lowVal to highVVal come next.3) All elements greater than highVVal appear in the end.The individual elements of three sets can appear in any order.
Examples:
Input: arr[] = {1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32} lowVal = 14, highVal = 20

A

A simple solution is to sort the array. This solution does a lot of extra rearrangements and requires O(n Log n) time.An efficient solution is based on Dutch National Flag based QuickSort. We traverse given array elements from left. We keep track of two pointers, first (called start in below code) to store next position of smaller element (smaller than range) from beginning; and second (called end in below code) to store next position of greater element from end.

// C++ program to implement three way
partitioning around a given range.
#include(iostream>
using namespace std;
// Partitions arr[0..n-1] around [lowVal..highVal]
void threeWayPartition(int arr[], int n,int lowVal, int highVal){
// Initialize ext available positions forsmaller (than range) and greater elements
int start = 0, end = n-1;
// Traverse elements from left
for (int i=0; i(=end;) {
// If current element is smaller thanrange, put it on next available smallerposition.
if (arr[i] ( lowVal){
//if i and start are same in that case we can’t swap.swap only if i is greater than start if(i==start){
start++;
i++;
}
else
swap(arr[i++], arr[start++]);
}
// If current element is greater thanrange, put it on next available greater position.
else if (arr[i] > highVal)
swap(arr[i], arr[end–]);
else
i++;
}
}
// Driver codeint main(){ int arr[] = {1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32}; int n = sizeof(arr)/sizeof(arr[0]);
threeWayPartition(arr, n, 10, 20);
cout (( “Modified array \n”; for (int i=0; i(n; i++) cout (( arr[i] (( “ “;}Output:
Modified array1 5 4 2 1 3 14 20 20 98 87 32 54Time Complexity: O(n)Auxiliary Space: O(1)

39
Q

Given an array arr of n positive integers and a number k. One can apply a swap operation on the array any number of times, i.e choose any two index i and j (i < j) and swap arr[i] , arr[j] . Find the minimum number of swaps required to bring all the numbers less than or equal to k together, i.e. make them a contiguous subarray.

Example 1:

Input : 
arr[ ] = {2, 1, 5, 6, 3} 
K = 3
Output : 
1
Explanation:
To bring elements 2, 1, 3 together,
swap index 2 with 4 (0-based indexing),
i.e. element arr[2] = 5 with arr[4] = 3
such that final array will be- 
arr[] = {2, 1, 3, 6, 5}

Example 2:

Input : 
arr[ ] = {2, 7, 9, 5, 8, 7, 4} 
K = 6 
Output :  
2 
Explanation: 
To bring elements 2, 5, 4 together, 
swap index 0 with 2 (0-based indexing)
and index 4 with 6 (0-based indexing)
such that final array will be- 
arr[] = {9, 7, 2, 5, 4, 7, 8}

Your Task:
This is a function problem. The input is already taken care of by the driver code. You only need to complete the function minSwap() that takes an array (arr), sizeOfArray (n), an integer K, and return the minimum swaps required. The driver code takes care of the printing.

Expected Time Complexity: O(N).
Expected Auxiliary Space: O(1).

A
class Solution
{
public:
    int minSwap(int arr[], int n, int k) {
        int window_size = 0;

for (int i = 0; i < n; i++) {
if (arr[i] <= k)
window_size++;
}

int good_elements = 0;

for(int i = 0; i < window_size; i++) {
if(arr[i] <= k)
good_elements++;
}

int max_good_elements = good_elements;

for(int i = 0; i < n - window_size; i++) {
if(arr[i] <= k)
good_elements–;
if(arr[i + window_size] <= k)
good_elements++;
max_good_elements = max(max_good_elements, good_elements);
}

return (window_size - max_good_elements);
}
};

40
Q

Given an array of positive integers. We need to make the given array a ‘Palindrome’. The only allowed operation is”merging” (of two adjacent elements). Merging two adjacent elements means replacing them with their sum. The task is to find the minimum number of merge operations required to make the given array a ‘Palindrome’.
To make any array a palindrome, we can simply apply merge operation n-1 times where n is the size of the array (because a single-element array is always palindromic, similar to single-character string). In that case, the size of array will be reduced to 1. But in this problem, we are asked to do it in the minimum number of operations.

Example :

Input : arr[] = {15, 4, 15}
Output : 0
Array is already a palindrome. So we
do not need any merge operation.

Input : arr[] = {1, 4, 5, 1}
Output : 1
We can make given array palindrome with
minimum one merging (merging 4 and 5 to
make 9)
Input : arr[] = {11, 14, 15, 99}
Output : 3
We need to merge all elements to make
a palindrome.
The expected time complexity is O(n).
A

Let f(i, j) be minimum merging operations to make subarray arr[i..j] a palindrome. If i == j answer is 0. We start i from 0 and j from n-1.

If arr[i] == arr[j], then there is no need to do any merging operations at index i or index j. Our answer in this case will be f(i+1, j-1).
Else, we need to do merging operations. Following cases arise.
If arr[i] > arr[j], then we should do merging operation at index j. We merge index j-1 and j, and update arr[j-1] = arr[j-1] + arr[j]. Our answer in this case will be 1 + f(i, j-1).
For the case when arr[i] < arr[j], update arr[i+1] = arr[i+1] + arr[i]. Our answer in this case will be 1 + f(i+1, j).
Our answer will be f(0, n-1), where n is the size of array arr[].
Therefore this problem can be solved iteratively using two pointers (first pointer pointing to start of the array and second pointer pointing to the last element of the array) method and keeping count of total merging operations done till now.
Below is an implementation of the above idea

.
// C++ program to find number of operations
// to make an array palindrome
#include 
using namespace std;
// Returns minimum number of count operations
// required to make arr[] palindrome
int findMinOps(int arr[], int n)
{
	int ans = 0; // Initialize result
	// Start from two corners
	for (int i=0,j=n-1; i<=j;)
	{
		// If corner elements are same,
		// problem reduces arr[i+1..j-1]
		if (arr[i] == arr[j])
		{
			i++;
			j--;
		}
		// If left element is greater, then
		// we merge right two elements
		else if (arr[i] > arr[j])
		{
			// need to merge from tail.
			j--;
			arr[j] += arr[j+1] ;
			ans++;
		}
		// Else we merge left two elements
		else
		{
			i++;
			arr[i] += arr[i-1];
			ans++;
		}
	}
return ans; }
// Driver program to test above
int main()
{
	int arr[] = {1, 4, 5, 9, 1};
	int n = sizeof(arr)/sizeof(arr[0]);
	cout << "Count of minimum operations is "
		<< findMinOps(arr, n) << endl;
	return 0;
}
41
Q

Median of two sorted arrays of same size

write 3 methods

A

There are 2 sorted arrays A and B of size n each. Write an algorithm to find the median of the array obtained after merging the above 2 arrays(i.e. array of length 2n). The complexity should be O(log(n)).
Note: Since the size of the set for which we are looking for the median is even (2n), we need to take the average of the middle two numbers and return the floor of the average.

Method 1 (Simply count while Merging) 
Use the 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 average of the elements at indexes n-1 and n in the merged array. See the below implementation.
// A Simple Merge based O(n)
// solution to find median of
// two sorted arrays
#include (bits/stdc++.h>
using namespace std;
/* This function returns
median of ar1[] and ar2[].
Assumptions in this function:
Both ar1[] and ar2[]
are sorted arrays
Both have n elements */
int getMedian(int ar1[],
			int ar2[], int n)
{
	int i = 0; /* Current index of
				i/p array ar1[] */
	int j = 0; /* Current index of
				i/p array ar2[] */
	int count;
	int m1 = -1, m2 = -1;
	/* Since there are 2n elements,
	median will be average of elements
	at index n-1 and n in the array
	obtained after merging ar1 and ar2 */
	for (count = 0; count (= n; count++)
	{
		/* Below is to handle case where
		all elements of ar1[] are
		smaller than smallest(or first)
		element of ar2[]*/
		if (i == n)
		{
			m1 = m2;
			m2 = ar2[0];
			break;
		}
		/*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;
		}
		/* equals sign because if two
		arrays have some common elements */
		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;
}

Output :
Median is 16

Time Complexity : O(n)
Auxiliary Space: O(1)

Method 2 (By comparing the medians of two arrays)
This method works by first getting medians of the two sorted arrays and then comparing them.
Let ar1 and ar2 be the input arrays.
Algorithm :
1) Calculate the medians m1 and m2 of the input arrays ar1[]
and ar2[] respectively.
2) If m1 and m2 both are equal then we are done.
return m1 (or m2)
3) If m1 is greater than m2, then median is present in one
of the below two subarrays.
a) From first element of ar1 to m1 (ar1[0…|n/2|])
b) From m2 to last element of ar2 (ar2[|n/2|…n-1])
4) If m2 is greater than m1, then median is present in one
of the below two subarrays.
a) From m1 to last element of ar1 (ar1[|n/2|…n-1])
b) From first element of ar2 to m2 (ar2[0…|n/2|])
5) Repeat the above process until size of both the subarrays
becomes 2.
6) If size of the two arrays is 2 then use below formula to get
the median.
Median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2
Examples :

ar1[] = {1, 12, 15, 26, 38}
ar2[] = {2, 13, 17, 30, 45}
For above two arrays m1 = 15 and m2 = 17
For the above ar1[] and ar2[], m1 is smaller than m2. So median is present in one of the following two subarrays.

[15, 26, 38] and [2, 13, 17]
Let us repeat the process for above two subarrays:

m1 = 26 m2 = 13. m1 is greater than m2. So the subarrays become  
  [15, 26] and [13, 17]
Now size is 2, so median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2
                       = (max(15, 13) + min(26, 17))/2 
                       = (15 + 17)/2
                       = 16
// A divide and conquer based
// efficient solution to find
// median of two sorted arrays
// of same size.
#include(bits/stdc++.h>
using namespace std;
/* to get median of a
sorted array */
int median(int [], int);
/* This function returns median
of ar1[] and ar2[].
Assumptions in this function:
	Both ar1[] and ar2[] are
	sorted arrays
	Both have n elements */
int getMedian(int ar1[],
			int ar2[], int n)
{
	/* return -1 for
	invalid input */
	if (n (= 0)
		return -1;
	if (n == 1)
		return (ar1[0] +
				ar2[0]) / 2;
	if (n == 2)
		return (max(ar1[0], ar2[0]) +
				min(ar1[1], ar2[1])) / 2;
	/* get the median of
	the first array */
	int m1 = median(ar1, n);
	/* get the median of
	the second array */
	int m2 = median(ar2, n);
	/* If medians are equal then
	return either m1 or m2 */
	if (m1 == m2)
		return m1;
	/* if m1 ( m2 then median must
	exist in ar1[m1....] and
				ar2[....m2] */
	if (m1 ( m2)
	{
		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;
}

Time Complexity : O(logn)
Auxiliary Space: O(1)
Algorithmic Paradigm: Divide and Conquer

Method 3 (By taking union w/o extra space)
This method works by taking the union of two arrays without extra space and then sorting them.

Algorithm :
1) Take the union of the input arrays ar1[] and ar2[].
2) Sort ar1[] and ar2[] respectively.
3) The median will be the last element of ar1[] + the first
element of ar2[] divided by 2. [(ar1[n-1] + ar2[0])/2].
Implementation :
// CPP program for the above approach
#include (bits/stdc++.h>
using namespace std;

/* This function returns
median of ar1[] and ar2[].
Assumptions in this function:
Both ar1[] and ar2[]
are sorted arrays
Both have n elements */
int getMedian(int ar1[], int ar2[], int n)
{
	int j = 0;
	int i = n - 1;
	while (ar1[i] > ar2[j] && j ( n && i > -1)
		swap(ar1[i--], ar2[j++]);
	sort(ar1, ar1 + n);
	sort(ar2, ar2 + n);
	return (ar1[n - 1] + ar2[0]) / 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;
}
42
Q

Median of two sorted arrays of different sizes
Given two sorted arrays, a[] and b[], the task is to find the median of these sorted arrays, in O(log n + log m) time complexity, when n is the number of elements in the first array, and m is the number of elements in the second array.
This is an extension of median of two sorted arrays of equal size problem. Here we handle arrays of unequal size also.

Example:

Input: ar1[] = {-5, 3, 6, 12, 15}
ar2[] = {-12, -10, -6, -3, 4, 10}
Output : The median is 3.
Explanation : The merged array is :
ar3[] = {-12, -10, -6, -5 , -3,
3, 4, 6, 10, 12, 15},
So the median of the merged array is 3

Input: ar1[] = {2, 3, 5, 8}
ar2[] = {10, 12, 14, 16, 18, 20}
Output : The median is 11.
Explanation : The merged array is :
ar3[] = {2, 3, 5, 8, 10, 12, 14, 16, 18, 20}
if the number of the elements are even,
so there are two middle elements,
take the average between the two :
(10 + 12) / 2 = 11.

A

Method 1: This method uses a linear and simpler approach.

Approach: The given arrays are sorted, so merge the sorted arrays in an efficient way and keep the count of elements inserted in the output array or printed form. So when the elements in the output array are half the original size of the given array print the element as a median element. There are two cases:

Case 1: m+n is odd, the median is at (m+n)/2 th index in the array obtained after merging both the arrays.
Case 2: m+n is even, the median will be average of elements at index ((m+n)/2 – 1) and (m+n)/2 in the array obtained after merging both the arrays
Algorithm:

Given two arrays are sorted. So they can be merged in O(m+n) time. Create a variable count to have a count of elements in the output array.
If the value of (m+n) is odd then there is only one median else the median is the average of elements at index (m+n)/2 and ((m+n)/2 – 1).
To merge the both arrays, keep two indices i and j initially assigned to 0. Compare the ith index of 1st array and jth index of second, increase the index of the smallest element and increase the count.
Store (m+n)/2 and (m+n)/2-1 in two variables (In the below C++ code, m1 and m2 are used for this purpose).
Check if the count reached (m+n) / 2. If (m+n) is odd return m1, If even return (m1+m2)/2.
Implementation:

// A Simple Merge based O(n) solution to find
// median of two sorted arrays
#include (bits/stdc++.h>
using namespace std;
/* This function returns median of ar1[] and ar2[].
Assumption in this function:
Both ar1[] and ar2[] are sorted arrays */
int getMedian(int ar1[], int ar2[], int n, int m)
{
	int i = 0; /* Current index of input array ar1[] */
	int j = 0; /* Current index of input array ar2[] */
	int count;
	int m1 = -1, m2 = -1;
	/*loop till (m+n)/2*/
	for (count = 0; count (= (m + n)/2; count++)
	{
		//store (n+m)/2-1 in m2
		m2=m1;
		if(i != n && j != m)
		{
			m1 = (ar1[i] > ar2[j]) ? ar2[j++] : ar1[i++];
		}
		else if(i ( n)
		{
			m1 = ar1[i++];
		}
		// for case when j(m,
		else
		{
			m1 = ar2[j++];
		}
	}
	// Since there are (n+m) elements,
	// There are following two cases
	// if n+m is odd then the middle
	// index is median i.e. (m+n)/2
	// other wise median will be average of elements
	// at index ((m+n)/2 - 1) and (m+n)/2
	// in the array obtained after merging ar1 and ar2
	if((m + n) % 2 == 1){
		return m1;
	}
	else{
		return (m1+m2)/2;
	}
}
/* Driver code */
int main()
{
	int ar1[] = {900};
	int ar2[] = {5,8,10,20};
	int n1 = sizeof(ar1)/sizeof(ar1[0]);
	int n2 = sizeof(ar2)/sizeof(ar2[0]);
	cout (( getMedian(ar1, ar2, n1, n2);
}
Output
10 
Complexity Analysis: 
Time Complexity: O(m + n). 
To merge both the arrays O(m+n) time is needed.
Space Complexity: O(1). 
No extra space is required.

Solution 4 : Binary Search
Approach: The given two arrays are sorted, so we can utilize the ability of Binary Search to divide the array and find the median.
Median means the point at which the whole array is divide into two parts. Hence since the two arrays are not merged so to get the median we require merging which is costly. Hence instead of merging we will use below given algorithm to efficiently find median.
Algorithm:
1. Lets assume that there are two arrays A and B with array A having the minimum number of elements.
If this is not the case than swap A and B to make A having small size.
2. The edge cases like one array is empty or both are empty will be handled.
3. let n be the size of A and m be the size of B.
Now think of an idea that if we have to find the median than we have to divide the whole merged array into two parts
namely left and right parts.
Now since we are given the size of left part (i.e (n+m+1)/2), Now look at below given example.

   A-> 1,2,3,4,5     n = 5
   B-> 1,2,3,4,5,6   m = 6

Here merged array will look like :- 1,1,2,2,3,3,4,4,5,5,6 and median then is 3 Now we can see our left part which is underlined. We divide A and B into two parts such that the 
sum of left part of both A and B will result in left part of merged array.

A-> 1,2,3,4,5     // pointers l =0 and r = n-1 hence mid = (l+r)/2;
   B -> 1,2,3,4,5,6

we can see that left part of A is given as n/2 and since total length of left part in merged array
is (m+n+1)/2, so left part of B = (m+n+1)/2-n/2;

Now we just have to confirm if our left and right partitions in A and B are correct or not.
  1. Now we have 4 variables indicating four values two from array A and two from array B.
    leftA -> Rightmost element in left part of A = 2
    leftb -> Rightmost element in left part of B = 4
    rightA -> Leftmost element in right part of A = 3
    rightB -> Leftmost element in right part of B = 5Hence to confirm that partition is correct we have to check the following conditions.
    leftA(=rightB and leftB(=rightA // This is the case when the sum of two parts of A and B results in left part of merged arrayif our partition not works that means we have to find other mid point in A and then left part in B
    This is seen whenleftA > rightB //means we have to dec size of A’s partition
    so do r = mid-1;
    else
    do l =mid+1;Hence repeat the above steps with new partitions till we get the answers.
  2. If leftA(=rightB and leftB(=rightA
    then we get correct partition and our answer depends on the total size of merged array (i.e. m+n)If (m+n)%2==0
    ans is max(leftA,leftB)+min(rightA,rightB)/2; // max of left part is nearest to median and min of right part is nearest to medain
    else
    ans is max(leftA,leftB);
#include (bits/stdc++.h>
using namespace std;
// Method to find median
double Median(vector(int>& A, vector(int>& B)
{
	int n = A.size();
	int m = B.size();
	if (n > m)
		return Median(B, A); // Swapping to make A smaller
int start = 0;
int end = n;
int realmidinmergedarray = (n + m + 1) / 2;

while (start (= end) {
	int mid = (start + end) / 2;
	int leftAsize = mid;
	int leftBsize = realmidinmergedarray - mid;
	int leftA
		= (leftAsize > 0)
			? A[leftAsize - 1]
			: INT_MIN; // checking overflow of indices
	int leftB
		= (leftBsize > 0) ? B[leftBsize - 1] : INT_MIN;
	int rightA
		= (leftAsize ( n) ? A[leftAsize] : INT_MAX;
	int rightB
		= (leftBsize ( m) ? B[leftBsize] : INT_MAX;
		// if correct partition is done
		if (leftA (= rightB and leftB (= rightA) {
			if ((m + n) % 2 == 0)
				return (max(leftA, leftB)
						\+ min(rightA, rightB))
					/ 2.0;
			return max(leftA, leftB);
		}
		else if (leftA > rightB) {
			end = mid - 1;
		}
		else
			start = mid + 1;
	}
	return 0.0;
}
// Driver code
int main()
{
	vector(int> arr1 = { -5, 3, 6, 12, 15 };
	vector(int> arr2 = { -12, -10, -6, -3, 4, 10 };
	cout (( "Median of the two arrays are" (( endl;
	cout (( Median(arr1, arr2);
	return 0;
}
43
Q

Given an integer array nums and an integer val, remove all occurrences of val in nums in-place. The order of the elements may be changed. Then return the number of elements in nums which are not equal to val.

Consider the number of elements in nums which are not equal to val be k, to get accepted, you need to do the following things:

Change the array nums such that the first k elements of nums contain the elements which are not equal to val. The remaining elements of nums are not important as well as the size of nums.
Return k.

A

Intuition
The intuition behind this solution is to iterate through the array and keep track of two pointers: index and i. The index pointer represents the position where the next non-target element should be placed, while the i pointer iterates through the array elements. By overwriting the target elements with non-target elements, the solution effectively removes all occurrences of the target value from the array.

Approach
Initialize index to 0, which represents the current position for the next non-target element.
Iterate through each element of the input array using the i pointer.
For each element nums[i], check if it is equal to the target value.
If nums[i] is not equal to val, it means it is a non-target element.
Set nums[index] to nums[i] to store the non-target element at the current index position.
Increment index by 1 to move to the next position for the next non-target element.
Continue this process until all elements in the array have been processed.
Finally, return the value of index, which represents the length of the modified array.
Complexity
Time complexity:
O(n)

Space complexity:
O(1)

Code
~~~
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int index = 0;
for(int i = 0; i< nums.size(); i++){
if(nums[i] != val){
nums[index] = nums[i];
index++;
}
}
return index;
}
};
~~~</int>

44
Q
A