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

Can be done using Moore algorithm

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

I’ll help you solve the merge intervals problem by creating a solution in Java. Let’s break this down step by step.

import java.util.*;

class Solution {
    public int[][] merge(int[][] intervals) {
        // If the input is empty or has only one interval, return as is
        if (intervals == null || intervals.length <= 1) {
            return intervals;
        }
        
        // Sort intervals based on start time
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        
        List<int[]> merged = new ArrayList<>();
        int[] currentInterval = intervals[0];
        merged.add(currentInterval);
        
        for (int[] interval : intervals) {
            // Get the current end time and next start time
            int currentEnd = currentInterval[1];
            int nextStart = interval[0];
            int nextEnd = interval[1];
            
            // If intervals overlap, update the end time if necessary
            if (currentEnd >= nextStart) {
                currentInterval[1] = Math.max(currentEnd, nextEnd);
            } else {
                // If no overlap, add the new interval to result
                currentInterval = interval;
                merged.add(currentInterval);
            }
        }
        
        // Convert List<int[]> to int[][]
        return merged.toArray(new int[merged.size()][]);
    }

    // Test the solution
    public static void main(String[] args) {
        Solution solution = new Solution();
        
        // Test case 1
        int[][] intervals1 = {{1,3}, {2,6}, {8,10}, {15,18}};
        int[][] result1 = solution.merge(intervals1);
        System.out.println("Test case 1:");
        printResult(result1);  // Expected: [[1,6], [8,10], [15,18]]
        
        // Test case 2
        int[][] intervals2 = {{1,4}, {4,5}};
        int[][] result2 = solution.merge(intervals2);
        System.out.println("\nTest case 2:");
        printResult(result2);  // Expected: [[1,5]]
    }
    
    private static void printResult(int[][] intervals) {
        System.out.print("[");
        for (int i = 0; i < intervals.length; i++) {
            System.out.print(Arrays.toString(intervals[i]));
            if (i < intervals.length - 1) System.out.print(", ");
        }
        System.out.println("]");
    }
}

Let me explain how this solution works:

  1. First, we handle edge cases:
    • If the input is null or has 1 or fewer intervals, we return it as is
  2. We sort the intervals based on start time:
    • This ensures we can process intervals in order
    • Makes it easier to find overlapping intervals
  3. Main merging logic:
    • Keep track of current interval and compare with next intervals
    • If intervals overlap (currentEnd >= nextStart), merge them by updating the end time
    • If no overlap, add the new interval to result list
  4. Time Complexity: O(n log n) due to sorting
    • Space Complexity: O(n) to store the result

The solution includes test cases for the examples you provided. The output will be:
~~~
Test case 1:
[[1,6], [8,10], [15,18]]

Test case 2:
[[1,5]]
~~~

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

Let me help you understand and solve this problem step by step. This is a classic algorithmic problem that requires finding the next lexicographically greater permutation of numbers.

First, let’s understand what makes one permutation “lexicographically greater” than another. Think of it like finding the next word in a dictionary - we want the smallest possible sequence that’s still larger than our current one.

The key insight is that to find the next permutation, we need to make the smallest possible change that increases the sequence. Here’s the systematic approach:

  1. Find the first pair of adjacent digits from the right where left < right (this identifies where we can make a change to get a larger number)
  2. Find the smallest number on the right that’s greater than the identified digit
  3. Swap these numbers
  4. Reverse the remaining digits to the right to get the smallest possible arrangement

Let me implement this solution in Java with detailed explanations:

class Solution {
    public void nextPermutation(int[] nums) {
        // Handle edge cases
        if (nums == null || nums.length <= 1) {
            return;
        }
        
        // Step 1: Find the first pair from right where nums[i] < nums[i+1]
        int i = nums.length - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        
        // If we found a valid pair (i >= 0)
        if (i >= 0) {
            // Step 2: Find the smallest number greater than nums[i] to its right
            int j = nums.length - 1;
            while (nums[j] <= nums[i]) {
                j--;
            }
            
            // Step 3: Swap the numbers at positions i and j
            swap(nums, i, j);
        }
        
        // Step 4: Reverse the subarray to the right of position i
        // This gives us the smallest possible arrangement of these digits
        reverse(nums, i + 1, nums.length - 1);
    }
    
    // Helper method to swap two elements in an array
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    
    // Helper method to reverse a portion of the array
    private void reverse(int[] nums, int start, int end) {
        while (start < end) {
            swap(nums, start++, end--);
        }
    }
}

Let’s walk through how this works with the example [1,2,3]:

  1. First iteration: Starting from right, we find that 2 < 3. This is our position i.
  2. Looking right from position i (2), we find 3 is the smallest number larger than 2.
  3. We swap 2 and 3, giving us [1,3,2].
  4. Since we only have one number to the right of position i, reversing it doesn’t change anything.
    Final result: [1,3,2]

Time Complexity: O(n) where n is the length of the array. We may need to scan the array twice in the worst case.
Space Complexity: O(1) as we’re only using a constant amount of extra space.

The beauty of this algorithm is that it handles all cases elegantly:
- When we can find a next permutation (like [1,2,3] → [1,3,2])
- When we’re at the last permutation (like [3,2,1] → [1,2,3])
- When we have duplicate numbers (like [1,1,5] → [1,5,1])

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
  1. Maximum Product

Given an integer arraynums, find a

subarray

that has the largest product, and returnthe product.

The test cases are generated so that the answer will fit in a32-bitinteger.

Example 1:

Input: nums = [2,3,-2,4] Output: 6 Explanation: [2,3] has the largest product 6.

Example 2:

Input: nums = [-2,0,-1] Output: 0 Explanation: The result cannot be 2, because [-2,-1] is not a subarray.

Constraints:

1 <= nums.length <= 2 * 104-10 <= nums[i] <= 10The product of any subarray ofnumsisguaranteedto fit in a32-bitinteger.

A

The provided solution solves the “Maximum Product Subarray” problem using a technique based on two passes through the array, leveraging prefix and suffix products. Here’s how the solution works:

class Solution { public int maxProduct(int[] nums) { int max = Integer.MIN_VALUE; int pre = 1, suf = 1; for(int i=0;i<nums.length;i++){ if(pre == 0) pre = 1; if(suf==0) suf = 1; pre = pre*nums[i]; suf = suf*nums[nums.length-i-1]; max = Math.max(max,Math.max(pre,suf)); } return max; } }

Core Idea:

  1. To find the maximum product subarray, the product can be influenced by:

Positive and negative numbers.

Zero (resetting the product calculation).

The position of negative numbers, which can turn the product positive when paired.

  1. The prefix and suffix traversal help ensure that the solution considers subarrays from both directions:

Prefix traversal checks products starting from the left.

Suffix traversal checks products starting from the right.

Solution Walkthrough:

  1. Initialization:

max: Holds the maximum product found so far, initialized to Integer.MIN_VALUE to ensure the result updates correctly.

pre and suf: These are used to calculate prefix and suffix products.

  1. Traversal:

Traverse the array from both the left (prefix) and the right (suffix) simultaneously.

Multiply the current element with pre for the prefix product and with suf for the suffix product.

  1. Handling Zeros:

If pre or suf becomes zero, reset them to 1. This is because a zero would “break” any ongoing product, so the subarray product calculation needs to restart.

  1. Update Maximum Product:

At each step, calculate the maximum product using the current prefix and suffix products.

Update max with the larger value between itself and the current pre or suf.

  1. Return Result:

After completing the loop, max holds the maximum product of any subarray.

Code Explanation with Example:

Input: nums = [2, 3, -2, 4]

First iteration (i = 0):

pre = 1 * 2 = 2

suf = 1 * 4 = 4

max = max(-2147483648, max(2, 4)) = 4

Second iteration (i = 1):

pre = 2 * 3 = 6

suf = 4 * (-2) = -8

max = max(4, max(6, -8)) = 6

Third iteration (i = 2):

pre = 6 * (-2) = -12

suf = -8 * 3 = -24

max = max(6, max(-12, -24)) = 6

Fourth iteration (i = 3):

pre = -12 * 4 = -48

suf = -24 * 2 = -48

max = max(6, max(-48, -48)) = 6

Final Result:

The maximum product is 6, achieved by the subarray [2, 3].

Input: nums = [-2, 0, -1]

First iteration (i = 0):

pre = 1 * -2 = -2

suf = 1 * -1 = -1

max = max(-2147483648, max(-2, -1)) = -1

Second iteration (i = 1):

pre = -2 * 0 = 0 (reset to 1 on zero)

suf = -1 * 0 = 0 (reset to 1 on zero)

max = max(-1, max(0, 0)) = 0

Third iteration (i = 2):

pre = 1 * -1 = -1

suf = 1 * -2 = -2

max = max(0, max(-1, -2)) = 0

Final Result:

The maximum product is 0, achieved by the subarray [0].

Complexity Analysis:

  1. Time Complexity:

Single pass through the array: , where is the length of nums.

  1. Space Complexity:

Constant space: , as only a few variables are used.

Key Takeaways:

This solution avoids explicitly generating all subarrays, making it efficient.

It ensures that both left-to-right and right-to-left products are considered, effectively handling negative numbers and zeros.

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

I’ll help you create a Java solution to find elements that appear more than n/k times in an array. I’ll implement two approaches: one using a HashMap and another using Moore’s Voting algorithm modified for n/k occurrences.

~~~
import java.util.*;

class FrequencyFinder {
// Solution 1: Using HashMap
public static List<Integer> findElementsHashMap(int[] arr, int k) {
int n = arr.length;
List<Integer> result = new ArrayList<>();</Integer></Integer>

    // Create a HashMap to store element frequencies
    Map<Integer, Integer> frequencyMap = new HashMap<>();
    
    // Count frequencies of all elements
    for (int num : arr) {
        frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
    }
    
    // Check which elements appear more than n/k times
    int threshold = n / k;
    for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
        if (entry.getValue() > threshold) {
            result.add(entry.getKey());
        }
    }
    
    return result;
}

// Solution 2: Modified Moore's Voting Algorithm
public static List<Integer> findElementsMoore(int[] arr, int k) {
    int n = arr.length;
    List<Integer> result = new ArrayList<>();
    
    // If array is empty or k is invalid
    if (n == 0 || k < 2) return result;
    
    // Step 1: Create an array of k-1 counters and k-1 elements
    int[][] candidates = new int[k-1][2];  // [element, count]
    
    // Step 2: Process all elements in array
    for (int num : arr) {
        boolean found = false;
        
        // Check if current element is present in candidates
        for (int i = 0; i < k-1; i++) {
            if (candidates[i][1] == 0) {
                candidates[i][0] = num;
                candidates[i][1] = 1;
                found = true;
                break;
            }
            else if (candidates[i][0] == num) {
                candidates[i][1]++;
                found = true;
                break;
            }
        }
        
        // If element is not present and there's space
        if (!found) {
            boolean reduced = false;
            // Reduce count of all candidates by 1
            for (int i = 0; i < k-1; i++) {
                if (candidates[i][1] > 0) {
                    candidates[i][1]--;
                    reduced = true;
                }
            }
        }
    }
    
    // Step 3: Check actual counts of candidate elements
    for (int i = 0; i < k-1; i++) {
        if (candidates[i][1] > 0) {
            int count = 0;
            for (int num : arr) {
                if (num == candidates[i][0]) {
                    count++;
                }
            }
            if (count > n/k) {
                result.add(candidates[i][0]);
            }
        }
    }
    
    return result;
}

// Main method with test cases
public static void main(String[] args) {
    // Test Case 1
    int[] arr1 = {4, 5, 6, 7, 8, 4, 4};
    int k1 = 3;
    System.out.println("Test Case 1:");
    System.out.println("Array: " + Arrays.toString(arr1));
    System.out.println("k = " + k1);
    System.out.println("Using HashMap: " + findElementsHashMap(arr1, k1));
    System.out.println("Using Moore's: " + findElementsMoore(arr1, k1));
    
    // Test Case 2
    int[] arr2 = {1, 1, 2, 2, 3, 5, 4, 2, 2, 3, 1, 1, 1};
    int k2 = 4;
    System.out.println("\nTest Case 2:");
    System.out.println("Array: " + Arrays.toString(arr2));
    System.out.println("k = " + k2);
    System.out.println("Using HashMap: " + findElementsHashMap(arr2, k2));
    System.out.println("Using Moore's: " + findElementsMoore(arr2, k2));
} }

I’ve implemented two different approaches to solve this problem:

  1. HashMap Approach (Time: O(n), Space: O(n)):
    • Count frequency of each element using a HashMap
    • Check which elements appear more than n/k times
    • Simple but requires extra space
  2. Modified Moore’s Voting Algorithm (Time: O(nk), Space: O(k)):
    • Uses k-1 counters to keep track of potential candidates
    • More space-efficient but slightly more complex
    • Better for scenarios where space is a constraint

The code includes test cases demonstrating both approaches. You can run the main method to see the output for different scenarios.

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 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;
36
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

include (iostream>using namespace std;

I’ll help you solve this problem step by step. Let’s first understand what we’re trying to do and then implement both the O(n) and O(n log n) solutions.

Let’s start with the O(n) solution using the sliding window technique:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // Edge case: if array is empty
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        int minLength = Integer.MAX_VALUE;  // Track the minimal length
        int currentSum = 0;                 // Sum of current window
        int start = 0;                      // Start of sliding window
        
        // Iterate through the array using the end pointer of our window
        for (int end = 0; end < nums.length; end++) {
            currentSum += nums[end];  // Add the current number to our window sum
            
            // While our window sum is >= target, try to minimize the window
            while (currentSum >= target) {
                // Update minLength if current window is smaller
                minLength = Math.min(minLength, end - start + 1);
                
                // Remove elements from start of window
                currentSum -= nums[start];
                start++;
            }
        }
        
        // If we never found a valid subarray, return 0
        return minLength == Integer.MAX_VALUE ? 0 : minLength;
    }
}

Now let’s understand how this solution works:

  1. We use a sliding window approach with two pointers: start and end.
  2. We expand our window by moving the end pointer and adding elements.
  3. When our window sum becomes ≥ target, we try to minimize it by moving the start pointer.
  4. We keep track of the minimum length found so far.

Now for the O(n log n) solution using binary search:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // Edge case: if array is empty
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        // Create prefix sum array
        int[] prefixSum = new int[nums.length + 1];
        for (int i = 1; i <= nums.length; i++) {
            prefixSum[i] = prefixSum[i-1] + nums[i-1];
        }
        
        int minLength = Integer.MAX_VALUE;
        
        // For each starting position, binary search for the ending position
        for (int start = 0; start < nums.length; start++) {
            // Binary search for the end position
            int targetSum = target + prefixSum[start];
            int end = binarySearch(prefixSum, start + 1, prefixSum.length, targetSum);
            
            if (end <= nums.length) {
                minLength = Math.min(minLength, end - start);
            }
        }
        
        return minLength == Integer.MAX_VALUE ? 0 : minLength;
    }
    
    // Binary search to find the first position where prefixSum[pos] >= target
    private int binarySearch(int[] prefixSum, int left, int right, int target) {
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (prefixSum[mid] >= target) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}

Let’s understand the O(n log n) solution:

  1. We first create a prefix sum array where prefixSum[i] represents the sum of all elements from index 0 to i-1.
  2. For each possible starting position, we use binary search to find the smallest ending position that gives us a sum ≥ target.
  3. The binary search helps us find this ending position in O(log n) time.
  4. Since we do this for each starting position (n times) and each binary search takes O(log n), the total time complexity is O(n log n).

The trade-offs between these solutions:
- The O(n) solution is more space-efficient (O(1) space) and generally faster in practice.
- The O(n log n) solution uses O(n) space for the prefix sum array but might be useful in scenarios where we need to handle multiple queries on the same array.

The sliding window solution is generally preferred because:
1. It’s more intuitive and easier to understand
2. It uses less memory
3. It has better time complexity
4. It processes the array in a single pass

37
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

Let me help you solve this interesting array partitioning problem. This is similar to the Dutch National Flag problem, but with a range instead of a single value. Let’s break it down step by step.

public class RangePartition {
    /**
     * Partitions an array around a given range [lowVal, highVal] into three parts:
     * 1. Elements less than lowVal
     * 2. Elements between lowVal and highVal (inclusive)
     * 3. Elements greater than highVal
     *
     * @param arr     The input array to be partitioned
     * @param lowVal  Lower bound of the range
     * @param highVal Upper bound of the range
     */
    public static void partitionRange(int[] arr, int lowVal, int highVal) {
        // Initialize three pointers
        int low = 0;        // elements < lowVal will be placed before this index
        int mid = 0;        // current element being examined
        int high = arr.length - 1;  // elements > highVal will be placed after this index

        // Continue until the middle pointer crosses the high pointer
        while (mid <= high) {
            if (arr[mid] < lowVal) {
                // If current element is less than lowVal, 
                // swap it to the low partition
                swap(arr, low, mid);
                low++;
                mid++;
            }
            else if (arr[mid] > highVal) {
                // If current element is greater than highVal,
                // swap it to the high partition
                swap(arr, mid, high);
                high--;
                // Don't increment mid as the swapped element needs to be examined
            }
            else {
                // If current element is within range,
                // leave it in the middle partition
                mid++;
            }
        }
    }

    /**
     * Helper method to swap two elements in an array
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * Utility method to print array contents
     */
    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }

    /**
     * Example usage of the partitionRange method
     */
    public static void main(String[] args) {
        int[] arr = {1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32};
        int lowVal = 14;
        int highVal = 20;

        System.out.println("Original array:");
        printArray(arr);

        partitionRange(arr, lowVal, highVal);

        System.out.println("Array after partitioning around range [" + 
                          lowVal + ", " + highVal + "]:");
        printArray(arr);
    }
}

Let me explain how this solution works:

  1. Algorithm Approach: We use a three-pointer technique, which is an extension of the Dutch National Flag partitioning algorithm:
    • low: Marks the boundary of elements less than lowVal
    • mid: Current element being examined
    • high: Marks the boundary of elements greater than highVal
  2. Partitioning Process: The algorithm maintains three regions:
    • Region 1: arr[0...low-1] contains elements < lowVal
    • Region 2: arr[low...mid-1] contains elements in range [lowVal, highVal]
    • Region 3: arr[high+1...end] contains elements > highVal
    • The area arr[mid...high] is the unknown region that still needs to be processed
  3. Time Complexity: O(n) where n is the length of the array
    • Each element is examined exactly once
    • The three-way partitioning requires at most n swaps
  4. Space Complexity: O(1)
    • The algorithm works in-place, using only a constant amount of extra space

To understand how it works, let’s walk through a small example:
~~~
int[] arr = {1, 14, 5, 20, 4}; // Initial array
lowVal = 10;
highVal = 15;

// After partitioning:
// Elements < 10: {1, 5, 4}
// Elements 10-15: {14}
// Elements > 15: {20}
~~~

Each element is processed exactly once, and depending on its value, it’s placed in the appropriate partition through swapping. The algorithm is stable in terms of maintaining the relative order within each partition, though the elements within each partition might be reordered.

38
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);
    }
};
39
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;
}
40
Q

4. Median of Two Sorted Arrays, solve in O((n + m)log(m + n)) time

Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.

The overall run time complexity should be O(log (m+n)).

Example 1:

Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
Example 2:

Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.

Constraints:

nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106

A
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int n = nums1.length;
        int m = nums2.length;
        int[] nums3 = new int[m + n];

        for (int i = 0; i < n; i++) {
            nums3[i] = nums1[i];
        }

        for (int i = 0; i < m; i++) {
            nums3[n + i] = nums2[i];
        }

        Arrays.sort(nums3);

        int length = n + m;

        if (length % 2 == 0) {
            double median = (double)(nums3[length / 2] + nums3[(length / 2) - 1]) / 2;
            return median;
        }

        return nums3[length / 2];
    }
}
41
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;
}
42
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.
Custom Judge:

The judge will test your solution with the following code:

int[] nums = […]; // Input array
int val = …; // Value to remove
int[] expectedNums = […]; // The expected answer with correct length.
// It is sorted with no values equaling val.

int k = removeElement(nums, val); // Calls your implementation

assert k == expectedNums.length;
sort(nums, 0, k); // Sort the first k elements of nums
for (int i = 0; i < actualLength; i++) {
assert nums[i] == expectedNums[i];
}
If all assertions pass, then your solution will be accepted.

Example 1:

Input: nums = [3,2,2,3], val = 3
Output: 2, nums = [2,2,,]
Explanation: Your function should return k = 2, with the first two elements of nums being 2.
It does not matter what you leave beyond the returned k (hence they are underscores).
Example 2:

Input: nums = [0,1,2,2,3,0,4,2], val = 2
Output: 5, nums = [0,1,4,0,3,,,_]
Explanation: Your function should return k = 5, with the first five elements of nums containing 0, 0, 1, 3, and 4.
Note that the five elements can be returned in any order.
It does not matter what you leave beyond the returned k (hence they are underscores).

Constraints:

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

A

I’ll solve this problem in Java and provide a comprehensive explanation that breaks down the solution step by step.

Let’s approach this problem with an in-place removal strategy that minimizes additional space usage:

class Solution {
    public int removeElement(int[] nums, int val) {
        // Initialize a pointer to track the position 
        // where non-val elements should be placed
        int k = 0;
        
        // Iterate through the entire array
        for (int i = 0; i < nums.length; i++) {
            // If the current element is not equal to val
            if (nums[i] != val) {
                // Move the element to the k-th position
                nums[k] = nums[i];
                // Increment the pointer for non-val elements
                k++;
            }
            // If the element equals val, we simply skip it
        }
        
        // Return the count of elements not equal to val
        return k;
    }
}

Let me break down this solution in detail to help you understand the approach:

Problem Understanding
The problem asks us to:
1. Remove all instances of a specific value from an array
2. Do this in-place (without creating a new array)
3. Return the count of remaining elements

Solution Strategy: Two-Pointer Technique
The solution uses a two-pointer approach:
- i is our scanning pointer that goes through the entire array
- k is our placement pointer that keeps track of where non-val elements should be placed

Step-by-Step Walkthrough

How the Algorithm Works
1. Start with k = 0, which represents the position where the next non-val element will be placed
2. Iterate through the array with pointer i
3. If the current element is not equal to val:
- Copy the current element to position k
- Increment k
4. If the current element is equal to val:
- Simply skip it (do nothing)
5. After the iteration, k represents the count of elements not equal to val

Example Walkthrough
Let’s trace the algorithm with the first example: nums = [3,2,2,3], val = 3

|———–|—–|—————-|————————|—–|————-|
| 1 | 0 | 3 | [3,2,2,3] | 0 | Skipped (matches val) |
| 2 | 1 | 2 | [2,2,2,3] | 1 | Moved to first position |
| 3 | 2 | 2 | [2,2,2,3] | 2 | Moved to second position |
| 4 | 3 | 3 | [2,2,2,3] | 2 | Skipped (matches val) |

Time and Space Complexity
- Time Complexity: O(n), where n is the length of the array
- We make a single pass through the array
- Space Complexity: O(1)
- We modify the array in-place
- We only use two pointers, regardless of array size

Key Insights
1. This method works by effectively “overwriting” val elements
2. The first k elements will contain only non-val elements
3. We don’t care about elements beyond index k

Potential Variations
While this solution is efficient, alternative approaches could include:
- Using two separate pointers (one from start, one from end)
- Using built-in array methods (though these typically create new arrays)

Common Pitfalls to Avoid
- Don’t create a new array
- Ensure you’re modifying the original array in-place
- Remember that k represents both the count and the placement index

Iteration | i | Current Element | nums after iteration | k | Explanation |

43
Q
A