Arrays
Arrays
Introduction to Arrays-
An array is a collection of items of the same data type stored at contiguous memory
locations. This makes it easier to calculate the position of each element by simply
adding an offset to a base value, i.e., the memory location of the first element of the
array (generally denoted by the name of the array).
For simplicity, we can think of an array as a fleet of stairs where on each step a
value is placed (let’s say one of your friends). Here, you can identify the location of
any of your friends by simply knowing the count of the step that they are on.
Remember: “Location of the next index depends on the data type that we use”.
The above image can be looked at as a top-level view of a staircase where you are
at the base of the staircase. Each element can be uniquely identified by their index
in the array (in a similar way where you could identify your friends by the step on
which they were on in the above example).
Defining an Array:
Array definition is similar to defining any other variable. There are two things that
are needed to be kept in mind, the data type of the array elements and the size of
the array. The size of the array is fixed and the memory for an array needs to be
allocated before use, the size of an array cannot be increased or decreased
dynamically.
dataType arrayName[arraySize];
Examples:
Searching in an Array
Searching for an element in an array means to check if a given element is present in
the array or not. This can be done by accessing elements of the array one by one
starting from the first element and checking whether any of the elements matches
with the given element.
We can use loops to perform the above operation of array traversal and access the
elements, using indexes.
Suppose the array is named arr[] with size N and the element to be searched is
referred to as key. Below is the algorithm to perform the search operation in the
given array.
Time Complexity of this search operation will be 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.
Insertion in Arrays
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:
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.
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.
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[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.
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.
len = len-1;
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 left.
Array Rotation-
As the term rotation signifies, array rotation means to rotate the elements of an array by
given positions.
Visually, the process of counter clock-wise array rotation(rotated by say K elements) looks
like:
Note: The similar approach can also be applied for clockwise array rotation.
Implementations
Simple Method: The simplest way to rotate an array is to implement the above visually
observed approach by using extra space.
leftRotate(arr[], d, n)
start
For i = 0 to i < d
Left rotate all elements of arr[] by one
end
Time Complexity: O(N*K), where N is the number of elements in the array and K is
the number of places by which elements will be rotated.
Auxiliary Space: O(1).
Juggling Algorithm:
This is an extension of the above method. Instead of moving one by one, divide the array in
different sets, where number of sets is equal to GCD of N and K and move the elements
within sets.
If GCD is 1 as is for the above example array (N = 7 and K = 2), then elements will be
moved within one set only, we just start with temp = arr[0] and keep moving arr[I+d] to
arr[I] and finally store temp at the right place.
Reversing an Array-
Reversing an array means reversing the order of elements in the given array.
Problem: Given an array of N elements. The task is to reverse the order of elements
in the given array.
For Example:
Input : arr[] = {1, 2, 3}
Output : arr[] = {3, 2, 1}
Iterative Solution
• Method 1 (Using Temporary Array): The idea is to first copy all of the
elements of the given array in a temporary array. Then traverse the
temporary array from end and replace elements in original array by elements
of temp array.
For Example:
Recursive Solution
The recursive approach is almost similar to that of the method 2 of the iterative
solution. Below is the recursive algorithm to reverse an array:
return;
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
Let’s start with a problem for illustration where we can apply this technique:
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
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 below representation will make it clear how the window slides over the array.
This is the initial phase where we have calculated the initial window sum starting
from index 0 . At this stage the window sum is 6. Now, we set the maximum_sum
as current_window i.e 6.
Now, we slide our window by a unit index. Therefore, now it discards 5 from the
window and adds 0 to the window. Hence, we will get our new window sum by
subtracting 5 and then adding 0 to it. So, our window sum now becomes 1. Now,
we will compare this window sum with the maximum_sum. As it is smaller we
wont the change the maximum_sum.
Similarly, now once again we slide our window by a unit index and obtain the new
window sum to be 2. Again we check if this current window sum is greater than the
maximum_sum till now. Once, again it is smaller so we don't change the
maximum_sum.
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,
Examples:
Below function generates a prefix sum array for a given array arr[] of size N:
prefixSum[0] = arr[0];
We can easily calculate the sum with-in a range [i, j] in an array using the prefix
sum array. Since the array prefixSum[i] stores the sum of all elements upto i.
Therefore, prefixSum[j] - prefixSum[i] will give:
sum of elements upto j-th index - sum of elements upto i-th element
prefixSum[j] - prefixSum[i-1]
Therefore,
sumInRange = prefixSum[j] , if i = 0
otherwise,
Sample Problem:
Consider an array of size N with all initial values as 0. Perform given 'm' add
operations from index 'a' to 'b' and evaluate highest element in array. An add
operation adds 100 to all elements from index a to b (both inclusive).
Example:
Explanation :
After I operation -
A : 0 100 100 100 0
After II operation -
A : 100 200 200 100 0
What we did was adding 100 at ‘a’ because this will add 100 to all elements while
taking prefix sum array. Subtracting 100 from ‘b+1’ will reverse the changes made
by adding 100 to elements from ‘b’ onward.
After I operation -
A : 0 100 0 0 -100
Prefix Sum Array : 0 100 100 100 0
After II operation -
A : 100 100 0 -100 -100
Prefix Sum Array : 100 200 200 100 0
Some of the most commonly used classes for implementing sequential lists or arrays are:
• Vector
• List
Vector
Vector in C++ STL is a class that represents a dynamic array. The advantages of vector over
normal arrays are,
Vectors are same as dynamic arrays with the ability to resize itself automatically when an
element is inserted or deleted, with their storage being handled automatically by the
container. Vector elements are placed in contiguous storage so that they can be accessed
and traversed using iterators. In vectors, data is inserted at the end. Inserting at the end
takes differential time, as sometimes there may be a need of extending the array. Removing
the last element takes only constant time because no resizing happens. Inserting and
erasing at the beginning or in the middle is linear in time.
To use the Vector class, include the below header file in your program:
Declaring Vector:
#include <iostream>
#include <vector>
int main()
vector<int> v;
// Push elements
v.push_back(i);
if (v.empty() == false)
else
v.emplace(v.begin(), 5);
v.emplace_back(20);
int n = v.size();
cout << "\nThe last element is: " << v[n - 1];
v.clear();
return 0;
Output:
Size : 5
Vector is not empty
Output of begin and end: 1 2 3 4 5
The first element is: 5
The last element is: 20
Vector size after erase(): 0
List
Lists are sequence containers that allow non-contiguous memory allocation. List in C++
STL implements a doubly linked list and not arrays. As compared to vector, list has slow
traversal, but once a position has been found, insertion and deletion are quick. Normally,
when we say a List, we talk about doubly linked lists. For implementing a singly linked list,
we can use forward_list class in C++ STL.
To use the List class, include the below header file in your program:
Declaring List:
#include <iostream>
#include <list>
#include <iterator>
int main()
gqlist1.push_back(i * 2);
gqlist2.push_front(i * 3);
showlist(gqlist1);
showlist(gqlist2);
gqlist1.pop_front();
showlist(gqlist1);
gqlist2.pop_back();
showlist(gqlist2);
gqlist1.reverse();
showlist(gqlist1);
gqlist2.sort();
showlist(gqlist2);
return 0;
Output:
List 1 (gqlist1) is : 0 2 4 6
8 10 12 14 16 18
List 2 (gqlist2) is : 27 24 21 18
15 12 9 6 3 0
gqlist1.front() : 0
gqlist1.back() : 18
gqlist1.pop_front() : 2 4 6 8
10 12 14 16 18
gqlist2.pop_back() : 27 24 21 18
15 12 9 6 3
gqlist1.reverse() : 18 16 14 12
10 8 6 4 2
gqlist2.sort(): 3 6 9 12
15 18 21 24 27
• begin() :- This function is used to return the beginning position of the container.
• end() :- This function is used to return the after end position of the container.
#include<iostream>
int main()
vector<int> ar = { 1, 2, 3, 4, 5 };
vector<int>::iterator ptr;
return 0;
• Output:
• advance() :- This function is used to increment the iterator position till the
specified number mentioned in its arguments.
// advance()
#include<iostream>
int main()
vector<int> ar = { 1, 2, 3, 4, 5 };
// points to 4
advance(ptr, 3);
return 0;
• Output:
• next() :- This function returns the new iterator that the iterator would point
after advancing the positions mentioned in its arguments.
• prev() :- This function returns the new iterator that the iterator would
point after decrementing the positions mentioned in its arguments.
#include<iostream>
int main()
vector<int> ar = { 1, 2, 3, 4, 5 };
// points to 4
// points to 3
return 0;
• Output:
// inserter()
#include<iostream>
int main()
vector<int> ar = { 1, 2, 3, 4, 5 };
advance(ptr, 3);
return 0;
Output:
The new vector after inserting elements is : 1 2 3 10 20 30 4 5
type array-name[];
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[];
Here,
Example:
OR
int[] intArray = new int[20]; // combining both statements in one
Implementation:
// Java program to illustrate creating an array
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
ArrayList is a part of the collection framework and is present in java.util package. It provides
us dynamic arrays in Java. Though it may be slower than standard arrays, it can be helpful
in programs where a lot of array manipulation is needed.
Implementation:
// 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]
1 2 3 5
• 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:
Implementation:
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]
Input
[4, 5, 3, 2, 5]
3
0 3
2 4
1 3
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.
Pseudo Code
// n : size of array
// q : Number of queries
// l, r : Finding Sum of range between index l and r
// l and r (inclusive) and 0 based indexing
void range_sum(arr, n)
{
prefix[n] = {0}
prefix[0] = arr[0]
for i = 1 to n-1 :
prefix[i] = a[i] + prefix[i-1]
for (i = 1 to q )
{
if (l == 0)
{
ans = prefix[r]
print(ans)
}
else
{
ans = prefix[r] - prefix[l-1]
print(ans)
}
}
}
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 -
We can iterate for each index i and calculate the leftsum and rightsum and check whether
they are equal.
if leftsum == rightsum :
return i
}
Time Complexity : O(n^2)
Auxiliary Space : O(1)
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
for (i=0 to n-1)
sum += arr[i]
We are given an array of positive and negative integers. We have to find the subarray
having maximum sum.
Input
[-3, 4, -1, -2, 1, 5]
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
if max_ending_here < 0 :
max_ending_here = 0
}
return max_so_far
}
Time Complexity : O(n)
Auxiliary Space : O(1)
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
1 3 4 6
2 5 7 8
Output
1 2 3 4 5 6 7 8
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
HIMANSHU KUMAR(LINKEDIN)
https://www.linkedin.com/in/himanshukumarmahuri
CREDITS- INTERNET.
DISCLOSURE- ALL THE DATA AND IMAGES ARE TAKEN FROM GOOGLE AND INTERNET.