Array based codes

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 19

ARRAYS

1. Subarray with 0 sum


[Paytm, Adobe]
Given an array of positive and negative numbers. Find if there is a subarray (of size at-least one) with 0
sum.
Example 1:
Input:
5
4 2 -3 1 6
Output:
Yes
Explanation:
2, -3, 1 is the subarray
with sum 0.
Example 2:
Input:
5
42016
Output:
Yes
Explanation:
0 is one of the element
in the array so there exist a
subarray with sum 0.
Your Task:
You only need to complete the function subArrayExists() that takes array and n as parameters and
returns true or false depending upon whether there is a subarray present with 0-sum or not. Printing
will be taken care by the driver’s code.
Expected Time Complexity: O(n).
Expected Auxiliary Space: O(n).
Constraints:
1 <= n <= 104
-105 <= a[i] <= 105
Solution
class SubArrayZeroSum{
public:
//Function to check whether there is a subarray present with 0-sum or not.
bool subArrayExists(int arr[], int n)
{
//using map to store the prefix sum which has appeared already.
unordered_map<int,bool> sumMap;

int sum = 0;
//iterating over the array.
for (int i = 0 ; i < n ; i++)
{
//storing prefix sum.
sum += arr[i];

//if prefix sum is 0 or if it is already present in map then it is


//repeated which means there is a subarray whose summation is 0,
//so we return true.
if (sum == 0 || sumMap[sum] == true)
return true;
//storing true in map for every prefix sum obtained.
sumMap[sum] = true;
}
//returning false if we don't get any subarray with 0 sum.
return false;
}
};
2. Trapping Rain Water
[Flipkart, Amazon, Microsoft, Google]
Given an array arr[] of N non-negative integers representing the height of blocks. If width of each block
is 1, compute how much water can be trapped between the blocks during the rainy season.
Example 1:
Input:
N=6
arr[] = {3,0,0,2,0,4}
Output:
10
Example 2:
Input:
N=4
arr[] = {7,4,0,9}
Output:
10
Explanation:
Water trapped by above
block of height 4 is 3 units and above
block of height 0 is 7 units. So, the
total unit of water trapped is 10 units.
Example 3:
Input:
N=3
arr[] = {6,9,9}
Output:
0
Explanation:
No water will be trapped.
Your Task:
You don't need to read input or print anything. The task is to complete the function trappingWater()
which takes arr[] and N as input parameters and returns the total amount of water that can be trapped.
Expected Time Complexity: O(N)
Expected Auxiliary Space: O(N)
Constraints:
3 < N < 106
0 < Ai < 108
class TrapRainWater{

// Function to find the trapped water between the blocks.


public:
long long trappingWater(int arr[], int n){

// left[i] contains height of tallest bar to the


// left of bar at ith index including itself.
vector<int> left(n, 0);

// right[i] contains height of tallest bar to


// the right of bar at ith index including itself.
vector<int> right(n, 0);

long long water = 0;

// Storing values of tallest bar from first index till ith index.
left[0] = arr[0];
for (int i = 1;i < n;i++) {
left[i] = max(left[i - 1], arr[i]);
}

// Storing values of tallest bar from last index till ith index.
right[n-1] = arr[n-1];
for (int i = n - 2;i >= 0;i--) {
right[i] = max(right[i + 1], arr[i]);
}

// Storing the result by choosing the minimum of heights of tallest bar to


// the right and left of the bar at current index and also subtracting the
// value of current index to get water accumulated at current index.
for (int i = 0;i < n;i++) {
water += max(0, min(left[i], right[i]) - arr[i]);
}
// returning the result.
return water;
}
};
3. Three-way partitioning
Given an array of size n and a range [a, b]. The task is to partition the array around the range such that
array is divided into three parts.
1) All elements smaller than a come first.
2) All elements in range a to b come next.
3) All elements greater than b appear in the end.
The individual elements of three sets can appear in any order. You are required to return the modified
array.
Note: The generated output is 1 if you modify the given array successfully.

Example 1:
Input:
n=5
A[] = {1, 2, 3, 3, 4}
[a, b] = [1, 2]
Output: 1
Explanation: One possible arrangement is:
{1, 2, 3, 3, 4}. If you return a valid
arrangement, output will be 1.
Example 2:
Input:
n=3
A[] = {1, 2, 3}
[a, b] = [1, 3]
Output: 1
Explanation: One possible arrangement
is: {1, 2, 3}. If you return a valid
arrangement, output will be 1.

Your Task:
You don't need to read input or print anything. The task is to complete the function threeWayPartition()
which takes the array[], a, and b as input parameters and modifies the array in-place according to the
given conditions.

Expected Time Complexity: O(n)


Expected Auxiliary Space: O(1)

Constraints:
1 <= n <= 106
1 <= A[i] <= 106
Solution
class threeWayPartition{
//Function to partition the array around the range such
//that array is divided into three parts.
public void threeWayPartition(int array[], int a, int b)
{
int n = array.length;
//Using two pointers which help in finding the index with which
//the elements need to be swapped if they are not in correct position.
int start = 0, end = n-1;

for (int i=0; i<=end;)


{
//If current element is smaller than lower range, we swap
//it with value on next available smallest position.
if (array[i] < a){
int temp = array[i];
array[i] = array[start];
array[start] = temp;
i++;
start++;
}
//If current element is greater than higher range, we swap
//it with value on next available greatest position.
else if (array[i] > b){
int temp = array[i];
array[i] = array[end];
array[end] = temp;
end--;
}

//Else we just move ahead in the array.


else
i++;
}
}
}
4. Factorials of large numbers
Given an integer N, find its factorial. return a list of integers denoting the digits that make up the
factorial of N.
Example 1:
Input: N = 5
Output: 120
Explanation: 5! = 1*2*3*4*5 = 120
Example 2:
Input: N = 10
Output: 3628800
Explanation:
10! = 1*2*3*4*5*6*7*8*9*10 = 3628800
Your Task:
You don't need to read input or print anything. Complete the function factorial() that takes integer N as
input parameter and returns a list of integers denoting the digits that make up the factorial of N.
Expected Time Complexity : O(N2)
Expected Auxilliary Space : O(1)
Constraints:
1 ≤ N ≤ 1000

Solution

class Solution{
public:
void multiply(int n, vector<int>& number) {
int carry = 0;
for (int i = 0; i < number.size(); i++) {
int num = n * number[i];
number[i] = (char)((num + carry) % 10);
carry = (num + carry) / 10;
}
while (carry) {
number.push_back(carry % 10);
carry /= 10;
}
}
vector<int> factorial(int N){
vector<int> number;
number.push_back(1);
for (int i = 2; i <= N; i++)
multiply(i, number);
reverse(number.begin(), number.end());
return number;
}

};
5. Minimum number of jumps
[Moonfrog Labs, Flipkart,Amazon,Microsoft,Housing.com,Walmart,Adobe,Google ]
Given an array of N integers arr[] where each element represents the maximum length of the jump 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 you cannot move through that element.

Note: Return -1 if you can't reach the end of the array.

Example 1:
Input:
N = 11
arr[] = {1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9}
Output: 3
Explanation:
First jump from 1st element to 2nd
element with value 3. Now, from here
we jump to 5th element with value 9,
and from here we will jump to the last.
Example 2:
Input:
N=6
arr = {1, 4, 3, 2, 6, 7}
Output: 2
Explanation:
First we jump from the 1st to 2nd element
and then jump to the last element.
Your task:
You don't need to read input or print anything. Your task is to complete function minJumps() which
takes the array arr and it's size N as input parameters and returns the minimum number of jumps. If not
possible return -1.

Expected Time Complexity: O(N)


Expected Space Complexity: O(1)

Constraints:
1 ≤ N ≤ 107
0 ≤ arri ≤ 107
Solution
class MinJumps {
public:
int minJumps(int arr[], int n)
{
// The number of jumps needed to reach the starting index is 0
if (n <= 1)
return 0;

// Return -1 if not possible to jump


if (arr[0] == 0)
return -1;

// initialization
int maxReach = arr[0]; // stores all time the maximal reachable index in the array.
int step = arr[0]; // stores the number of steps we can still take
int jump =1;//stores the number of jumps necessary to reach that maximal reachable position.

// Start traversing array


int i=1;
for (i = 1; i < n; i++)
{
// Check if we have reached the end of the array
if (i == n-1)
return jump;

// updating maxReach
maxReach = max(maxReach, i+arr[i]);

// we use a step to get to the current index


step--;

// If no further steps left


if (step == 0)
{
// we must have used a jump
jump++;

// Check if the current index/position or lesser index


// is the maximum reach point from the previous indexes
if(i >= maxReach)
return -1;

// re-initialize the steps to the amount


// of steps to reach maxReach from position i.
step = maxReach - i;
}
}

return -1;
}
};
6. Find the median of an array
Given an array arr[] of N integers, calculate the median
Example 1:
Input: N = 5
arr[] = 90 100 78 89 67
Output: 89
Explanation: After sorting the array
middle element is the median
Example 2:
Input: N = 4
arr[] = 56 67 30 79
Output: 61
Explanation: In case of even number of elements, average of two middle elements
is the median.
Your Task:
You don't need to read or print anything. Your task is to complete the function
find_median() which takes the array as input parameter and returns the floor value of
the median.

Expected Time Complexity: O(n * log(n))


Expected Space Complexity: O(1)

Constraints:
1 <= Length of Array <= 100
1 <= Elements of Array <= 100
Solution
class Median
{
public:
public:
int find_median(vector<int> v)
{
sort(v.begin(),v.end());
int ans ;
// if size is odd
if(v.size() & 1)
ans = v[v.size() / 2];
// If size is even
else
ans = (v[v.size() / 2] + v[v.size() / 2 - 1]) / 2;
return ans;
}
};
7. Median of two sorted arrays of same size
There are 2 sorted arrays A and B of size n each. Write an algorithm to find the median
of the array obtained after merging the above 2 arrays(i.e. array of length 2n). The
complexity should be O(log(n))
Input: ar1[]={1,12,15,26,38}
ar2[]={2,13,16,30,45}
Output: 16
Explanation: After merging two arrays we get {1,2,12,13,15,17,26,30,38,45}. Middle
two elements are 15, 17. Average of middle two elements (15+17)/2=16

Note: Since the size of the set for which we are looking for the median is even (2n), we
need to take the average of the middle two numbers and return the floor of the
average

Solution

// A Simple Merge based O(n) solution to find median of two sorted arrays
#include <stdio.h>

/* This function returns median of ar1[] and ar2[].


Assumptions in this function:
Both ar1[] and ar2[] are sorted arrays and both have n elements */
int getMedian(int ar1[], int ar2[], int n)
{
int i = 0; /* Current index of i/p array ar1[] */
int j = 0; /* Current index of i/p array ar2[] */
int count;
int m1 = -1, m2 = -1;
/* Since there are 2n elements, median will be average of elements at index n-
1 and n in the array obtained after merging ar1 and ar2 */
for (count = 0; count <= n; count++)
{
/*Below is to handle case where all elements of ar1[] are
smaller than smallest(or first) element of ar2[]*/
if (i == n)
{
m1 = m2;
m2 = ar2[0];
break;
}

/*Below is to handle case where all elements of ar2[] are smaller than
smallest(or first) element of ar1[]*/
else if (j == n)
{
m1 = m2;
m2 = ar1[0];
break;
}
/* equals sign because if two arrays have some common elements */
if (ar1[i] <= ar2[j])
{
m1 = m2; /* Store the prev median */
m2 = ar1[i];
i++;
}
else
{
m1 = m2; /* Store the prev median */
m2 = ar2[j];
j++;
}
}
return (m1 + m2)/2;
}

int main()
{
int ar1[] = {1, 12, 15, 26, 38};
int ar2[] = {2, 13, 17, 30, 45};

int n1 = sizeof(ar1)/sizeof(ar1[0]);
int n2 = sizeof(ar2)/sizeof(ar2[0]);
if (n1 == n2)
printf("Median is %d", getMedian(ar1, ar2, n1));
else
printf("Doesn't work for arrays of unequal size");
return 0;
}
Method 2 (By comparing the medians of two arrays)
This method works by first getting medians of the two sorted arrays and then
comparing them.
Let ar1 and ar2 be the input arrays.
Algorithm :
1) Calculate the medians m1 and m2 of the input arrays ar1[] and ar2[] respectively.
2) If m1 and m2 both are equal then we are done, return m1 (or m2)
3) If m1 is greater than m2, then median is present in one of the below two subarrays.
a) From first element of ar1 to m1 (ar1[0...|_n/2_|])
b) From m2 to last element of ar2 (ar2[|_n/2_|...n-1])
4) If m2 is greater than m1, then median is present in one of the below two subarrays.
a) From m1 to last element of ar1 (ar1[|_n/2_|...n-1])
b) From first element of ar2 to m2 (ar2[0...|_n/2_|])
5) Repeat the above process until size of both the subarrays becomes 2.
6) If size of the two arrays is 2 then use below formula to get the median.
Median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2
Examples:
ar1[] = {1, 12, 15, 26, 38}
ar2[] = {2, 13, 17, 30, 45}
For above two arrays m1 = 15 and m2 = 17
For the above ar1[] and ar2[], m1 is smaller than m2. So median is present in one of
the following two subarrays.
[15, 26, 38] and [2, 13, 17]
Let us repeat the process for above two subarrays:
m1 = 26 m2 = 13.
m1 is greater than m2. So the subarrays become
[15, 26] and [13, 17]
Now size is 2, so median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2
= (max(15, 13) + min(26, 17))/2
= (15 + 17)/2
= 16
Solution

/* A Java program to divide and conquer based efficient solution to find median of two
sorted arrays of same size.*/
import java.util.*;
class medianSameSize {
/* This function returns median of ar1[] and ar2[].
Assumptions in this function:
Both ar1[] and ar2[] are sorted arrays Both have n elements */
static int getMedian(
int[] a, int[] b, int startA,
int startB, int endA, int endB)
{
if (endA - startA == 1) {
return (Math.max(a[startA],b[startB])+ Math.min(a[endA], b[endB]))/ 2;
}
/* get the median of the first array */
int m1 = median(a, startA, endA);
/* get the median of the second array */
int m2 = median(b, startB, endB);
/* If medians are equal then return either m1 or m2 */
if (m1 == m2) {
return m1;
}
/* if m1 < m2 then median must exist in ar1[m1....] and ar2[....m2] */
else if (m1 < m2) {
return getMedian(a, b, (endA + startA + 1) / 2,startB, endA,
(endB + startB + 1) / 2);
}
/* if m1 > m2 then median must exist in ar1[....m1] and ar2[m2...] */
else {
return getMedian(a, b, startA, (endB + startB + 1) / 2,
(endA + startA + 1) / 2, endB);
}
}
/* Function to get median of a sorted array */
static int median(int[] arr, int start, int end)
{
int n = end - start + 1;
if (n % 2 == 0) {
return (arr[start + (n / 2)] + arr[start + (n / 2 - 1)])/ 2;
}
else {
return arr[start + n / 2];
}
}
public static void main(String[] args)
{
int ar1[] = { 1, 2, 3, 6 };
int ar2[] = { 4, 6, 8, 10 };
int n1 = ar1.length;
int n2 = ar2.length;
if (n1 != n2) {
System.out.println("Doesn't work for arrays "+"of unequal size");
}
else if (n1 == 0) {
System.out.println("Arrays are empty.");
}
else if (n1 == 1) {
System.out.println((ar1[0] + ar2[0]) / 2);
}
else {
System.out.println("Median is "+ getMedian(ar1, ar2, 0, 0,
ar1.length - 1, ar2.length - 1));
}
}
}
8. Find minimum number of merge operations to make an array palindrome
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.

Algorithm
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.

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).
2. Else, we need to do merging operations. Following cases arise.
a. 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).
b. 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).
3. Our answer will be f(0, n-1), where n is the size of array arr[].

// Java program to find number of operations to make an array palindrome

class mergePallindrome
{
// Returns minimum number of count operations
// required to make arr[] palindrome
static 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;
}
public static void main(String[] args)
{
int arr[] = new int[]{1, 4, 5, 9, 1} ;
System.out.println("Count of minimum operations is "+
findMinOps(arr, arr.length));
}
}
9. Given Array of size n and a number k, find all elements that appear more than n/k
times
Given an array of size n and an integer k, find all elements in the array that appear
more than n/k times.

Examples:

Input: arr[] = {3, 1, 2, 2, 1, 2, 3, 3}, k = 4


Output: {2, 3}
Explanation: Here n/k is 8/4 = 2, therefore 2 appears 3 times in the array that is
greater than 2 and 3 appears 3 times in the array that is greater than 2

Input: arr[] = {9, 8, 7, 9, 2, 9, 7}, k = 3


Output: {9}
Explanation: Here n/k is 7/3 = 2, therefore 9 appears 3 times in the array that is
greater than 2.
Steps:
- First, make a frequency map of all the elements in the array
- Then traverse the map and check the frequency of every element
- If the frequency is greater than n/k then print the element.
Solution
// Java Code to find elements whose
// frequency yis more than n/k
import java.util.*;

public class ElementNK


{
public static void morethanNdK(int a[], int n, int k)
{
int x = n / k;

// Hash map initialization


HashMap<Integer, Integer> y = new HashMap<>();

// count the frequency of each element.


for (int i = 0; i < n; i++) {
// is element doesn't exist in hash table
if (!y.containsKey(a[i]))
y.put(a[i], 1);

// if element does exist in the hash table


else {
int count = y.get(a[i]);
y.put(a[i], count + 1);
}
}

// iterate over each element in the hash table and check their
frequency, // if it is more than n/k, print it.
for (Map.Entry m : y.entrySet()) {
Integer temp = (Integer)m.getValue();
if (temp > x)
System.out.println(m.getKey());
}
}
public static void main(String[] args)
{
int a[] = new int[] { 1, 1, 2, 2, 3, 5, 4, 2, 2, 3, 1, 1, 1 };
int n = 12;
int k = 4;
morethanNdK(a, n, k);
}
}
10. Chocolate Distribution Problem
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 between maximum chocolates and minimum
chocolates
is 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 ≤ 100
1 ≤ N ≤ 105
1 ≤ Ai ≤ 109
1≤M≤N
Solution
class MinDiff {
public long findMinDiff (ArrayList<Integer> a, int n, int m)
{
Collections.sort(a);

int start = 0,end =0;


// Largest number of chocolates
int mind = Integer.MAX_VALUE;

// 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 = a.get(i+m-1) - a.get(i);
if(mind>diff)
{
mind = diff;
start = i;
end = i+m-1;
}
}
return a.get(end)-a.get(start);
}
}

You might also like