Arrays Article GFG - Copy
Arrays Article GFG - Copy
What is an Array?
An array is a collection of items of the same variable type stored that are stored at
contiguous memory locations. It’s one of the most popular and simple data structures and is
often used to implement other data structures. Each item in an array is indexed starting with
0.
The dream of every programmer is to become not just a good, but also a great programmer.
We all want to achieve our goals and to achieve our goals, we must have a great plan with us.
In this context, we have decided to provide a complete guide for Arrays interview
preparation, which will help you to tackle the problems that are mostly asked in the interview,
such as What is an Array, What is Array in C language, How do you initialize an Array in C, How
to sort an Array, etc. We have also covered the topics such as Top Theoretical interview
questions and Top interview coding questions in this complete guide for Array interview
preparation.
Representation of Array
The representation of an array can be defined by its declaration. A declaration means
allocating memory for an array of a given size.
Array
Arrays can be declared in various ways in different languages. For better illustration, below
are some language-specific array declarations.
C++Java
*/
// The syntax of declaring a static array is:
= {<data1>, <data2>,…..<dataN> };
// Example:
int arr[] = { 2, 5, 6, 9, 7, 4, 3 };
Array declaration
However, the above declaration is static or compile-time memory allocation, which means
that the array element’s memory is allocated when a program is compiled. Here only a fixed
size (i,e. the size that is mentioned in square brackets []) of memory will be allocated for
storage, but don’t you think it will not be the same situation as we know the size of the array
every time, there might be a case where we don’t know the size of the array. If we declare a
larger size and store a lesser number of elements will result in a wastage of memory or either
be a case where we declare a lesser size then we won’t get enough memory to store the rest
of the elements. In such cases, static memory allocation is not preferred.
What it means is that, we can use normal variables (v1, v2, v3, ..) when we have a small
number of objects. But if we want to store a large number of instances, it becomes difficult to
manage them with normal variables. The idea of an array is to represent many instances in
one variable..
OR
type[] array-name;
An array declaration has two components: the type and the name. Type declares the element
type of the array. The element type determines the data type of each element that comprises
the array. Like an array of type int, we can also create an array of other primitive data types
such as char, float, double..etc, or user-defined data type(objects of a class). Thus, the
element type for the array determines what type of data the array will hold.
For Example:
// both are valid declarations
int intArray[];
or int[] intArray;
byte byteArray[];
short shortsArray[];
boolean booleanArray[];
long longArray[];
float floatArray[];
double doubleArray[];
char charArray[];
Instantiating an Array: When an array is declared, only a reference of the array is created. To
actually create or give memory to the array, you create an array like this:
array-name = new type [size];
Here,
type specifies the type of data being allocated.
size specifies the number of elements in the array.
array-name is the name of array variable that is linked to the array.
Example:
int intArray[]; //declaring array
OR
int[] intArray = new int[20]; // combining both statements in one
Accessing Java Array Elements using for Loop: Each element in the array is accessed by its
index. The index begins with 0 and ends at (total array size)-1. All the elements of array can be
accessed using Java for Loop as shown below.
class GFG
int[] arr;
arr[0] = 10;
arr[1] = 20;
// so on...
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
Output:
Element at index 0 : 10
Element at index 1 : 20
Element at index 2 : 30
Element at index 3 : 40
Element at index 4 : 50
Java also provides some inbuilt classes which can be used for implementing arrays or
sequential lists. Let's look at some of these in detail.
ArrayList in Java
Implementation:
Java
// ArrayList in Java
import java.io.*;
import java.util.*;
class arrayli
throws IOException
// size of ArrayList
int n = 5;
arrli.add(i);
// Printing elements
System.out.println(arrli);
arrli.remove(3);
System.out.println(arrli);
System.out.print(arrli.get(i)+" ");
Output:
[1, 2, 3, 4, 5]
[1, 2, 3, 5]
1235
The Vector class implements a growable array of objects. Vectors basically falls in legacy
classes but now it is fully compatible with collections.
Vector implements a dynamic array that means it can grow or shrink as required. Like an
array, it contains components that can be accessed using an integer index.
They are very similar to ArrayList but Vector is synchronized and has some legacy
method, which the collection framework does not contain.
It extends AbstractList and implements List interfaces.
Constructor:
Vector(): Creates a default vector of initial capacity 10.
Vector(int size): Creates a vector whose initial capacity is specified by size.
Vector(int size, int incr): Creates a vector whose initial capacity is specified by size and
the increment is specified by incr. It specifies the number of elements to allocate each
time a vector is resized upwards.
Vector(Collection c): Creates a vector that contains the elements of collection c.
Implementation:
Java
import java.util.*;
class Vector_demo {
// Create a vector
v.add(1);
v.add(2);
v.add(3);
v.add(4);
v.add(3);
Output:
Vector is [1, 2, 3, 4, 3]
Operations on Arrays
Types of Array operations:
Traversal: Traverse through the elements of an array.
Insertion: Inserting a new element in an array.
CC++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
static int insert(int arr[], int n, int x, int cap, int pos)
if(n == cap)
return n;
arr[i + 1] = arr[i];
arr[idx] = x;
return n + 1;
System.out.println("Before Insertion");
System.out.print(arr[i]+" ");
System.out.println();
int x = 7, pos = 2;
System.out.print(arr[i]+" ");
CC++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
if(arr[i] == x)
return i;
return -1;
}
public static void main(String args[])
Disadvantages of Array:
As arrays have a fixed size, once the memory is allocated to them, it cannot be increased
or decreased, making it impossible to store extra data if required. An array of fixed size is
referred to as a static array.
Allocating less memory than required to an array leads to loss of data.
An array is homogeneous in nature so, a single array cannot store values of different data
types.
Arrays store data in contiguous memory locations, which makes deletion and insertion
very difficult to implement. This problem is overcome by implementing linked lists, which
allow elements to be accessed randomly.
Application of Array:
They are used in the implementation of other data structures such as array lists, heaps,
hash tables, vectors, and matrices.
Database records are usually implemented as arrays.
It is used in lookup tables by computer.
It is used for different sorting algorithms such as bubble sort insertion sort, merge sort,
and quick sort
Insertion and Deletion in Arrays
Insertion in Arrays
1.
Given an array of a given size. The task is to insert a new element in this array. There are
two possible ways of inserting elements in an array:
Insert elements at the end of the array.
2. Insert element at any given index in the array.
Special Case: A special case is needed to be considered is that whether the array is
already full or not. If the array is full, then the new element can not be inserted.
Consider the given array is arr[] and the initial size of the array is N, that is the array can
contain a maximum of N elements and the length of the array is len. That is, there are len
number of elements already present in this array.
Insert an element K at end in arr[]: The first step is to check if there is any space left in
the array for new element. To do this check,
if(len < N)
// space left
else
// array is full
If there is space left for the new element, insert it directly at the end at position len + 1
and index len:
arr[len] = k;
Time Complexity of this insert operation is constant, i.e. O(1) as we are directly inserting
the element in a single operation.
Insert an element K at position, pos in arr[]: The first step is to check if there is any space
left in the array for new element. To do this check,
if(len < N)
// space left
else
// array is full
Now, if there is space left, the element can be inserted. The index of the new element will
be idx = pos - 1. Now, before inserting the element at the index idx, shift all elements from
the index idx till end of the array to the right by 1 place. This can be done as:
arr[i+1] = arr[i];
arr[idx] = K;
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.
Deletion in Arrays
To delete a given element from an array, we will have to first search the element in the array.
If the element is present in the array then delete operation is performed for the element
otherwise the user is notified that the array does not contains the given element.
Consider the given array is arr[] and the initial size of the array is N, that is the array can
contain a maximum of N elements and the length of the array is len. That is, there are len
number of elements already present in this array.
Deleting an element K from the array arr[]: Search the element K in the array arr[] to find the
index at which it is present.
for(i = 0; i < N; i++)
if(arr[i] == K)
idx = i; return;
else
Now, to delete the element present at index idx, left shift all of the elements present after idx
by one place and finally reduce the length of the array by 1.
for(i = idx+1; i < len; i++)
arr[i-1] = arr[i];
len = len-1;
Time Complexity in worst case of this deletion operation can be linear i.e. O(N) as we might
have to shift all of the elements by one place to the left.
Description : We are given an Array of n integers, We are given q queries having indices l and r
. We have to find out sum between the given range of indices.
Input
[4, 5, 3, 2, 5]
03
24
13
Output
14 (4+5+3+2)
10 (3+2+5)
10 (5+3+2)
Solution : The numbers of queries are large. It will be very inefficient to iterate over the array
and calculate the sum for each query separately. We have to devise the solution so that we
can get the answer of the query in constant time. We will be storing the sum upto a particular
index in prefix sum Array. We will be using the prefix sum array to calculate the sum for the
given range.
prefix[] = Array stores the sum (A[0]+A[1]+....A[i]) at index i.
if l == 0 :
sum(l,r) = prefix[r]
else :
Pseudo Code
// n : size of array
// q : Number of queries
void range_sum(arr, n)
prefix[n] = {0}
prefix[0] = arr[0]
for i = 1 to n-1 :
for (i = 1 to q )
{
if (l == 0)
ans = prefix[r]
print(ans)
else
print(ans)
Description - Equilibrium index of an array is an index such that the sum of elements at lower
indexes is equal to the sum of elements at higher indexes. We are given an Array of integers,
We have to find out the first index i from left such that -
A[0] + A[1] + ... A[i-1] = A[i+1] + A[i+2] ... A[n-1]
Input
[-7, 1, 5, 2, -4, 3, 0]
Output
3
Naive Solution : We can iterate for each index i and calculate the leftsum and rightsum and
check whether they are equal.
for (i=0 to n-1)
leftsum = 0
for (j = 0 to i-1)
leftsum += arr[i]
rightsum = 0
rightsum += arr[i]
if leftsum == rightsum :
return i
Tricky Solution : The idea is to first get the total sum of array. Then Iterate through the array
and keep updating the left sum which is initialized as zero. In the loop, we can get the right
sum by subtracting the elements one by one. Then check whether the Leftsum and the
Rightsum are equal.
Pseudo Code
// n : size of array
int eqindex(arr, n)
{
sum = 0
leftsum = 0
sum += arr[i]
sum -= a[i]
if (sum == leftsum )
return i
leftsum += a[i]
Description : We are given an array of positive and negative integers. We have to find the
subarray having maximum sum.
Input
Output
7
(4+(-1)+(-2)+1+5)
Solution :A simple idea is to look for all the positive contiguous segments of the array
(max_ending_here is used for this), and keep the track of maximum sum contiguous segment
among all the positive segments (max_so_far is used for this). Each time we get a positive sum
compare it with max_so_far and if it is greater than max_so_far, update max_so_far.
Pseudo Code
//n : size of array
int largestsum(arr, n)
max_so_far = INT_MIN
max_ending_here = 0
max_ending_here += arr[i]
max_so_far = max_ending_here
if max_ending_here < 0 :
max_ending_here = 0
return max_so_far
}
Time Complexity : O(n)
Auxiliary Space : O(1)
Description : We are given two sorted arrays arr1[ ] and arr2[ ] of size m and n respectively.
We have to merge these arrays and store the numbers in arr3[ ] of size m+n.
Input
1346
2578
Output
12345678
Solution : The idea is to traverse both the arrays simultaneously and compare the current
numbers from both the Arrays. Pick the smaller element and copy it to arr3[ ] and advance
the current index of the array from where the smaller element is picked. When we reach at
the end of one of the arrays, copy the remaining elements of another array to arr3[ ].
Pseudo Code
// input arrays - arr1(size m), arr2(size n)
i=0,j=0,k=0
arr3[k++] = arr1[i++]
else :
arr3[k++] = arr2[j++]
}
while(i < m)
arr3[k++] = arr1[i++]
while(j < n)
arr3[k++] = arr2[j++]
Example:
C++Java
import java.io.*;
import java.lang.*;
import java.math.*;
import java.util.*;
class GFG {
{
for (int i = 0; i < n; ++i) {
flag = false;
break;
if (flag == true) {
return arr[i];
return -1;
throws IOException
Output
Approach 2 – Linear Traversal: One of the most simplest and basic approach to solve this
problem is to simply traverse the whole list and find the maximum among them.
C++Java
class Test
int i;
max = arr[i];
return max;
}
// Driver method
Output
Example:
Implementation:
C++Java
// element in an array
class GFG {
elements */
int arr_size)
if (arr_size < 2) {
return;
}
second = first;
first = arr[i];
second = arr[i];
if (second == Integer.MIN_VALUE)
+ " element\n");
else
int n = arr.length;
print2largest(arr, n);
Complexity Analysis:
Examples:
Input : 20 21 45 89 89 90
Output : Yes
Input : 20 20 45 89 89 90
Output : Yes
Input : 20 20 78 98 99 97
Output : No
Naive Approach:
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
return false;
return true;
System.out.println(isSorted(arr, n));
Output:
false
Iterative approach:
C++Java
class GFG {
if (n == 0 || n == 1)
return true;
return false;
return true;
// driver code
int n = arr.length;
if (arraySortedOrNot(arr, n))
System.out.print("Yes\n");
else
System.out.print("No\n");
Output
Yes
Reverse an Array
Given an array (or string), the task is to reverse the array/string.
Examples :
Iterative way :
C++Java
// array
start to end*/
int temp;
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
array on a line */
static void printArray(int arr[],
int size)
System.out.println();
// Driver code
printArray(arr, 6);
rvereseArray(arr, 0, 5);
printArray(arr, 6);
Output :
123456
Reversed array is
654321
Examples:
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
temp[0] = arr[0];
int res = 1;
if(temp[res - 1] != arr[i])
temp[res] = arr[i];
res++;
arr[i] = temp[i];
return res;
System.out.println("Before Removal");
System.out.print(arr[i]+" ");
}
System.out.println();
n = remDups(arr, n);
System.out.println("After Removal");
System.out.print(arr[i]+" ");
Output
Before Removal
10 20 20 30 30 30
After Removal
10 20 30
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
{
int res = 1;
if(arr[res - 1] != arr[i])
arr[res] = arr[i];
res++;
return res;
System.out.println("Before Removal");
System.out.print(arr[i]+" ");
}
System.out.println();
n = remDups(arr, n);
System.out.println("After Removal");
System.out.print(arr[i]+" ");
Output
Before Removal
10 20 20 30 30 30
After Removal
10 20 30
Algorithm:
moveZerosToEnd(arr, n)
Initialize count = 0
for i = 0 to n-1
if (arr[i] != 0) then
arr[count++]=arr[i]
for i = count to n-1
arr[i] = 0
C++Java
import java.io.*;
class GFG {
int count = 0;
arr[count++] = arr[i];
arr[i]=0;
7, 0, 6, 0, 9};
int n = arr.length;
printArray(arr, n);
moveZerosToEnd(arr, n);
printArray(arr, n);
}
Output
Original array: 0 1 9 8 4 0 0 2 7 0 6 0 9
Modified array: 1 9 8 4 2 7 6 9 0 0 0 0 0
Examples:
Input:
arr[] = {1, 2, 3, 4, 5, 6, 7}, d = 2
Output: 3 4 5 6 7 1 2
Naive:
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
arr[i - 1] = arr[i];
arr[n - 1] = temp;
lRotateOne(arr, n);
System.out.println("Before Rotation");
System.out.print(arr[i]+" ");
}
System.out.println();
leftRotate(arr, d, n);
System.out.println("After Rotation");
System.out.print(arr[i]+" ");
Output:
Before Rotation
12345
After Rotation
34512
Efficient Approach:
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
temp[i] = arr[i];
arr[i - d] = arr[i];
arr[n - d + i] = temp[i];
{
int arr[] = {1, 2, 3, 4, 5}, n = 5, d = 2;
System.out.println("Before Rotation");
System.out.print(arr[i]+" ");
System.out.println();
leftRotate(arr, d, n);
System.out.println("After Rotation");
System.out.print(arr[i]+" ");
Output:
Before Rotation
12345
After Rotation
34512
Reversal Method:
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
temp[i] = arr[i];
arr[i - d] = arr[i];
}
for(int i = 0; i < d; i++)
arr[n - d + i] = temp[i];
System.out.println("Before Rotation");
System.out.print(arr[i]+" ");
System.out.println();
leftRotate(arr, d, n);
System.out.println("After Rotation");
System.out.print(arr[i]+" ");
}
Output
Before Rotation
12345
After Rotation
34512
For example:
Naive Approach: The problem can be solved based on the idea mentioned below:
Use two loops. The outer loop runs from 0 to size – 1 and one by one pick all elements from
left to right. The inner loop compares the picked element to all the elements on its right side.
If the picked element is greater than all the elements to its right side, then the picked
element is the leader.
We run a loop from the first index to the 2nd last index.
And for each index, we run another loop from the next index to the last index.
If all the values to the right of that index are smaller than the index, we simply add the
value in our answer data structure.
C++Java
class LeadersInArray
int j;
if (arr[i] <=arr[j])
break;
lead.printLeaders(arr, n);
Output
17 5 2
The idea is to scan all the elements from right to left in an array and keep track of the
maximum till now. When the maximum changes its value, print it.
Illustration:
We start from the last index position. The last position is always a leader, as there are no
elements towards its right.
And then we iterate on the array till we reach index position = 0.
Each time we keep a check on the maximum value
Every time we encounter a maximum value than the previous maximum value
encountered, we either print or store the value as it is the leader
C++Java
class LeadersInArray
{
max_from_right = arr[i];
int n = arr.length;
lead.printLeaders(arr, n);
}
}
Output
2 5 17
Examples :
Method 1 (Simple)
Use two loops. In the outer loop, pick elements one by one and in the inner loop calculate the
difference of the picked element with every other element in the array and compare the
difference with the maximum difference calculated so far. Below is the implementation of the
above approach :
C++Java
class MaximumDifference
{
/* The function assumes that there are at least two
elements in array.
int i, j;
return max_diff;
maxdif.maxDiff(arr, 5));
}
Output :
C++Java
class MaximumDifference
elements in array.
int i;
for (i = 1; i < arr_size; i++)
min_element = arr[i];
return max_diff;
System.out.println("MaximumDifference is " +
maxdif.maxDiff(arr, size));
Output:
Examples:
Naive Approach: The simplest approach is to traverse the array and keep the count of every
element encountered in a HashMap and then, in the end, print the frequencies of every
element by traversing the HashMap. This approach is already implemented here.
Efficient Approach: The above approach can be optimized in terms of space used based on
the fact that, in a sorted array, the same elements occur consecutively, so the idea is to
maintain a variable to keep track of the frequency of elements while traversing the array.
Follow the steps below to solve the problem:
C++Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
int freq = 1;
freq++;
// Otherwise,
else {
System.out.println("Frequency of "
+ arr[i - 1]
freq = 1;
// Driver Code
// Given Input
int arr[]
= { 1, 1, 1, 2, 3, 3, 5, 5, 8, 8, 8, 9, 9, 10 };
int N = arr.length;
// Function Call
printFreq(arr, N);
Output
Frequency of 1 is: 3
Frequency of 2 is: 1
Frequency of 3 is: 2
Frequency of 5 is: 2
Frequency of 8 is: 3
Frequency of 9 is: 2
Frequency of 10 is: 1
Our Task: The cost of a stock on each day is given in an array. Find the maximum profit that
you can make by buying and selling on those days. If the given array of prices is sorted in
decreasing order, then profit cannot be earned at all.
Examples:
We have 2 approaches to solve the problem: Naive Approach and Efficient Approach
1) Naive Approach
A simple approach is to try buying the stocks and selling them every single day when
profitable and keep updating the maximum profit so far.
C++Java
import java.util.*;
class GFG {
return 0;
int profit = 0;
// must be bought
int curr_profit
= price[j] - price[i]
+ maxProfit(price, start, i - 1)
+ maxProfit(price, j + 1, end);
return profit;
// Driver code
int n = price.length;
System.out.print(maxProfit(price, 0, n - 1));
}
Output
865
Time Complexity: O(n2), Trying to buy every stock and exploring all possibilities.
Auxiliary Space: O(1)
In this approach, we just need to find the next greater element and subtract it from the
current element so that the difference keeps increasing until we reach a minimum. If the
sequence is a decreasing sequence, so the maximum profit possible is 0.
maxProfit = 0
if price[i] > price[i – 1]
maxProfit = maxProfit + price[i] – price[i – 1]
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
int profit = 0;
for(int i = 1; i < n; i++)
return profit;
System.out.println(maxProfit(arr, n));
Output
13
Examples:
An element of the array can store water if there are higher bars on the left and the right.
The amount of water to be stored in every position can be found by finding the heights
of bars on the left and right sides.
The total amount of water stored is the summation of the water stored in each index.
Approach 1 (Brute Approach): This approach is the brute approach. The idea is to:
Traverse every array element and find the highest bars on the left and right sides. Take the
smaller of two heights. The difference between the smaller height and the height of the
current element is the amount of water that can be stored in this array element.
C++Java
class GFG {
int res = 0;
}
// Find maximum element on its right
return res;
// Driver code
int[] arr = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
int n = arr.length;
System.out.print(maxWater(arr, n));
Output
Complexity Analysis:
Time Complexity: O(N2). There are two nested loops traversing the array.
Space Complexity: O(1). No extra space is required.
In previous approach, for every element we needed to calculate the highest element on the
left and on the right.
For every element we can precalculate and store the highest bar on the left and on the
right (say stored in arrays left[] and right[]).
Then iterate the array and use the precalculated values to find the amount of water
stored in this index,
which is the same as ( min(left[i], right[i]) – arr[i] )
Illustration:
For i = 0:
=> left[0] = 3, right[0] = 4 and arr[0] = 3
=> Water stored = min(left[0], right[0]) – arr[0] = min(3, 4) – 3 = 3 – 3 = 0
=> Total = 0 + 0 = 0
For i = 1:
=> left[1] = 3, right[1] = 4 and arr[1] = 0
=> Water stored = min(left[1], right[1]) – arr[1] = min(3, 4) – 0 = 3 – 0 = 3
=> Total = 0 + 3 = 3
For i = 2:
=> left[2] = 3, right[2] = 4 and arr[2] = 2
=> Water stored = min(left[2], right[2]) – arr[2] = min(3, 4) – 2 = 3 – 2 = 1
=> Total = 3 + 1 = 4
For i = 3:
=> left[3] = 3, right[3] = 4 and arr[3] = 0
=> Water stored = min(left[3], right[3]) – arr[3] = min(3, 4) – 0 = 3 – 0 = 3
=> Total = 4 + 3 = 7
For i = 4:
=> left[4] = 4, right[4] = 4 and arr[4] = 4
=> Water stored = min(left[4], right[4]) – arr[4] = min(4, 4) – 4 = 4 – 4 = 0
=> Total = 7 + 0 = 7
So total rain water trapped = 7
Create two arrays left[] and right[] of size N. Create a variable (say max) to store the
maximum found till a certain index during traversal.
Run one loop from start to end:
In each iteration update max and also assign left[i] = max.
Run another loop from end to start:
In each iteration update max found till now and also assign right[i] = max.
Traverse the array from start to end.
The amount of water that will be stored in this column is min(left[i], right[i]) – array[i]
Add this value to the total amount of water stored
Print the total amount of water stored.
C++Java
class Test {
= new int[] { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
// Initialize result
int water = 0;
left[0] = arr[0];
// right[i]) - arr[i] .
return water;
System.out.println(findWater(arr.length));
Output
Complexity Analysis:
Time Complexity: O(N). Only one traversal of the array is needed, So time Complexity is
O(N).
Space Complexity: O(N). Two extra arrays are needed, each of size N.
Examples:
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:
1. Initialize 3 variables endIndex to 0, currMax, and globalMax to first value of the input
array.
2. 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.
3. 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.
4. Now print the subarray between [start, end].
C++Java
import java.util.*;
class GFG{
// of the array
// Update currMax
currMax = Math.max(nums.get(i),
nums.get(i) + currMax);
// than globalMax
globalMax = currMax;
endIndex = i;
globalMax -= nums.get(startIndex);
if (globalMax == 0)
break;
// Driver Code
arr.add(-2);
arr.add(-5);
arr.add(6);
arr.add(-2);
arr.add(-3);
arr.add(1);
arr.add(5);
arr.add(-6);
// Function call
SubarrayWithMaxSum(arr);
}
Output
6 -2 -3 1 5
Examples:
Naive approach:
The idea is to consider every subarray and find the length of even and odd subarrays.
C++Java
// Java program for above approach
import java.io.*;
import java.util.ArrayList;
import java.util.List;
int n)
// Length of longest
// alternating subarray
int ans = 1;
int cnt = 1;
if ((a.get(j - 1) % 2 == 0
&& a.get(j) % 2 != 0)
|| (a.get(j - 1) % 2 != 0
&& a.get(j) % 2 == 0))
cnt++;
else
break;
// so return 0 if ans = 1
if (ans == 1)
return 0;
return ans;
// Drivers code
List.of(1, 2, 3, 4, 5, 7, 8));
int n = a.size();
System.out.println(longestEvenOddSubarray(a, n));
}
Output
Time Complexity: O(N2), Iterating over every subarray therefore N2 are possible
Auxiliary Space: O(1)
C++Java
import java.util.*;
class GFG {
{
if (n == 0)
return 0;
int maxLength = 0;
// remainder = 1, it is odd
int curLength = 1;
// nature or not
if (arr[i] % 2 != prevOdd)
curLength++;
else
curLength = 1;
// subarray is found
maxLength = curLength;
// updating even/odd nature of prev
prevOdd = arr[i] % 2;
return maxLength;
int[] arr = { 1, 2, 3, 4, 5, 3, 7, 2, 9, 4 };
// length = 5
int n = arr.length;
System.out.print(
System.out.print(maxEvenOdd(arr, n));
Output
Time Complexity: O(N), Since we need to iterate over the whole array once
Auxiliary Space: O(1)
Maximum Circular Sum Subarray
Given a circular array of size n, find the maximum subarray sum of the non-empty subarray.
Examples:
Naive Approach:
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
int index = (i + j) % n;
curr_sum += arr[index];
return res;
System.out.println(maxCircularSum(arr, n));
}
Output
12
Time Complexity: O(n*n), where n is the number of elements in the input array.
Auxiliary Space: O(1), No extra space is required.
Efficient Approach:
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
return res;
}
static int overallMaxSum(int arr[], int n)
if(max_normal < 0)
return max_normal;
int arr_sum = 0;
arr_sum += arr[i];
arr[i] = -arr[i];
Output
12
Time Complexity: O(n), where n is the number of elements in the input array.
Auxiliary Space: O(1), No extra space is required
Majority Element
Find the majority element in the array. A majority element in an array A[] of size n is an
element that appears more than n/2 times (and hence there is at most one such element).
Examples :
Input : {3, 3, 4, 2, 4, 4, 2, 4, 4}
Output : 4
Explanation: The frequency of 4 is 5 which is greater than the half of the size of the array
size.
Input : {3, 3, 4, 2, 4, 4, 2, 4}
Output : No Majority Element
Explanation: There is no element whose frequency is greater than the half of the size of the
array size.
The basic solution is to have two loops and keep track of the maximum count for all different
elements. If the maximum count becomes greater than n/2 then break the loops and return
the element having the maximum count. If the maximum count doesn’t become more than
n/2 then the majority element doesn’t exist.
Illustration:
For i = 0:
count = 0
Loop over the array, whenever an element is equal to arr[i] (is 3), increment count
count of arr[i] is 2, which is less than n/2, hence it can’t be majority element.
For i = 1:
count = 0
Loop over the array, whenever an element is equal to arr[i] (is 4), increment count
count of arr[i] is 5, which is greater than n/2 (i.e 4), hence it will be majority element.
C++Java
// element in an array
import java.io.*;
class GFG {
// in an array
int maxCount = 0;
int index = -1; // sentinels
int count = 0;
if (arr[i] == arr[j])
count++;
maxCount = count;
index = i;
if (maxCount > n / 2)
System.out.println(arr[index]);
else
// Driver code
int arr[] = { 1, 1, 2, 1, 3, 5, 1 };
int n = arr.length;
// Function calling
findMajority(arr, n);
Output
Time Complexity: O(n*n), A nested loop is needed where both the loops traverse the array
from start to end.
Auxiliary Space: O(1), No extra space is required.
The first step gives the element that may be the majority element in the array. If there is
a majority element in an array, then this step will definitely return majority element,
otherwise, it will return candidate for majority element.
Check if the element obtained from the above step is the majority element. This step is
necessary as there might be no majority element.
Illustration:
maj_index = 0, count = 1
At i = 1: arr[maj_index] != arr[i]
count = count – 1 = 1 – 1 = 0
now count == 0 then:
maj_index = i = 1
count = count + 1 = 0 + 1 = 1
At i = 2: arr[maj_index] != arr[i]
count = count – 1 = 1 – 1 = 0
now count == 0 then:
maj_index = i = 2
count = count + 1 = 0 + 1 = 1
At i = 3: arr[maj_index] != arr[i]
count = count – 1 = 1 – 1 = 0
now count == 0 then:
maj_index = i = 3
count = count + 1 = 0 + 1 = 1
At i = 4: arr[maj_index] != arr[i]
count = count – 1 = 1 – 1 = 0
now count == 0 then:
maj_index = i = 4
count = count + 1 = 0 + 1 = 1
At i = 5: arr[maj_index] == arr[i]
count = count + 1 = 1 + 1 = 2
At i = 6: arr[maj_index] == arr[i]
count = count + 1 = 2 + 1 = 3
At i = 7: arr[maj_index] == arr[i]
count = count + 1 = 3 + 1 = 4
Therefore, the arr[maj_index] may be the possible candidate for majority element.
Now, Again traverse the array and check whether arr[maj_index] is the majority element or
not.
arr[maj_index] is 4
Loop through each element and maintains a count of the majority element, and a
majority index, maj_index
If the next element is the same then increment the count if the next element is not the
same then decrement the count.
if the count reaches 0 then change the maj_index to the current element and set the
count again to 1.
Now again traverse through the array and find the count of the majority element found.
If the count is greater than half the size of the array, print the element
Else print that there is no majority element
C++Java
class MajorityElement {
else
if (a[maj_index] == a[i])
count++;
else
count--;
if (count == 0) {
maj_index = i;
count = 1;
return a[maj_index];
int i, count = 0;
if (a[i] == cand)
count++;
return true;
else
return false;
}
/* Driver code */
MajorityElement majorelement
= new MajorityElement();
// Function call
majorelement.printMajority(a, size);
Output
No Majority Element
Time Complexity: O(n), As two traversal of the array, is needed, so the time complexity is
linear.
Auxiliary Space: O(1), As no extra space is required
Our Task: Given a binary array, we need to convert this array into an array that either contains
all 1s or all 0s. We need to do it using the minimum number of group flips.
Examples :
Input : arr[] = {1, 1, 0, 0, 0, 1}
Output : From 2 to 4
Explanation : We have two choices, we make all 0s or do all 1s. We need to do two group flips
to make all elements 0 and one group flip to make all elements 1. Since making all elements
1 takes the least group flips, we do this.
We have 2 approaches to solve the problem: Naive Approach and Efficient Approach
1) Naive Approach:
A Naive Solution is to
There are only two types of groups (groups of 0s and groups of 1s)
Either the counts of both groups are same or the difference between counts is at most 1.
For example, in {1, 1, 0, 1, 0, 0} there are two groups of 0s and two groups of 1s. In
example, {1, 1, 0, 0, 0, 1, 0, 0, 1, 1}, count of groups of 1 is one more than the counts of 0s.
Based on the above facts, we can conclude that if we always flip the second group and other
groups that of the same type as the second group, we always get the correct answer. In the
first case, when group counts are the same, it does not matter which group type we flip as
both will lead to the correct answer. In the second case, when there is one extra, by ignoring
the first group and starting from the second group, we convert this case to first case (for
subarray beginning from the second group) and get the correct answer.
C++Java
import java.io.*;
import java.util.*;
class GFG {
// as previous
// to be flipped.
if (arr[i] != arr[0])
else
System.out.println(i - 1);
// last interval
if (arr[n - 1] != arr[0])
System.out.println(n - 1);
}
// Driver code
int n = arr.length;
printGroups(arr, n);
Output
From 1 to 2
From 6 to 7
Our Task: Given an array of integers of size 'n'. Our aim is to calculate the maximum sum of 'k'
consecutive elements in the array.
Examples :
We have 2 approaches to solve the problem: Naive Approach and Efficient Approach
1) Naive Approach:
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.
C++Java
import java.util.*;
import java.io.*;
import java.lang.*;
class GFG
int sum = 0;
}
max_sum = Math.max(max_sum, sum);
return max_sum;
System.out.println(maxSum(arr, n, k));
Output
45
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.
1. We compute the sum of first k elements out of n terms using a linear loop and store the
sum in variable window_sum.
2. Then we will graze linearly over the array till it reaches the end and simultaneously keep
track of maximum sum.
3. 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 .
The representation shown below will make it clear how the window slides over the array.
C++Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
int curr_sum = 0;
curr_sum += arr[i];
return max_sum;
System.out.println(maxSum(arr, n, k));
Output
40
Examples :
To fill the prefix sum array, we run through index 1 to last and keep on adding the present
element with the previous value in the prefix sum array.
Below is the implementation :
Implementation:
C++JavaPython
import java.io.*;
class PrefixArray {
preArray[0] = arr[0];
int n = arr.length;
Output
10 14 30 50
Output
10 14 30 50
Given an array arr[] of size n. Given Q queries and in each query given L and R, print sum of
array elements from index L to R.
Implementation:
C++JavaPython
import java.io.*;
class PrefixArray {
preArray[0] = arr[0];
}
}
int arr[] = { 3, 6, 2, 8, 9, 2 };
int n = arr.length;
int q = 4;
int queries[][] = { { 2, 3 }, { 4, 6 }, { 1, 5 }, { 3, 6 } };
int l = queries[i][0] - 1;
int r = queries[i][1] - 1;
if( l - 1 > 0 ) {
} else {
}
Output
8 19 28 21
Our Task: Given two arrays L[ ] and R[ ] of size N where L[i] and R[i] (0 ≤ L[i], R[i] < 106)
denotes a range of numbers, the task is to find the maximum occurred integer in all the
ranges. If more than one such integer exists, print the smallest one.
Examples:
We have 2 approaches to solve the problem: Naive Approach and Efficient Approach
1) Naive Approach:
Traverse through all the ranges. Then for every range, count frequencies, make a hash table
(array) to store every item. Then traverse through other ranges and increment the frequency
of every item. The item with the highest frequency is our answer.
Below is the implementation of the above approach:
C++Java
freq[j]++;
int res = 0;
res = i;
return res;
int[] L = { 1, 5, 9, 13, 21 };
int n = L.length;
System.out.println(maximumOccurredElement(L, R, n));
Output:
5
Time Complexity: O(N*M). Here N is the number of ranges and M is the maximum number of
elements in any of the ranges.
Auxiliary Space: O(M). For Hash table.
2) Efficient Approach:
The idea is to use the Difference array technique. Create a vector initialized with value zero.
Iterate through every range and mark the presence of the beginning of every range by
incrementing the start of the range with one i.e. arr[L[i]]++ and mark the end of the range by
decrementing at index one greater than the end of range by one i.e. arr[R[i]+1]–.
Now when computing the prefix sum, Since the beginning is marked with one, all the values
after beginning will be incremented by one. Now as increment is only targeted only till the
end of the range, the decrement on index R[i]+1 prevents that for every range i.
Illustration:
2. For end of range arr[R[i]+1]– the array becomes {0,1,1,1,-1, 0, -1, 0,-1,……}
Do prefix sum, the sum of elements after (1) is incremented by one because beginning was
marked. Now elements after (3) must not be incremented so if there’s a range one, two,
three, the values from one, two, three should only be incremented by one or their frequency
should be incremented by one.
That is why decreasing the value of arr[R[i]+1] is needed so that elements after the end of
this range have minus one subtracted to values. That is how to nullify the impact of
incrementing the value when prefix will be taken.
So when taking the prefix, simply decrement every value after the range ends, since I want to
increment elements only in the range. That’s the idea of this algorithm.
Initialize a Hash array arr[] to store the occurrence of every element in all the ranges
combined.
Iterate over all the N ranges and increment L[i] by one and decrement R[i] by one.
Run a Loop from 1 to the maximum end value of all the ranges and take the Prefix sum.
C++Java
import java.io.*;
class GFG {
int n)
// subtracting 1 at Ri index.
arr[L[i]] += 1;
arr[R[i] + 1] -= 1;
maxi = R[i];
}
}
int ind = 0;
msum = arr[i];
ind = i;
return ind;
// Driver program
int[] L = { 1, 4, 9, 13, 21 };
int n = L.length;
System.out.println(maximumOccurredElement(L, R, n));
Output
5