In C++, the Standard Template Library (STL) provides a set of programming tools to implement algorithms and data structures like vectors, lists, queues, etc. This repository contains entire C++ STL Library which anyone require while doing Competitive Programming, Contest solving or in Online Assessment.
Join us for all the latest offcampus job updates, webinar, hackathons, resume review and a lot more β€οΈβ€οΈ
- Vector In C++
- Stack In C++
- Queue In C++
- Deque In C++
- Priotity Queue In C++
- Set In C++
- Unordered Set In C++
- Multiset In C++
- Unordered Multiset In C++
- Map In C++
- Unordered Map In C++
- MultiMap In C++
- Unordered MultiMap In C++
A vector is a dynamic array whose size can be changed automatically when an element is inserted or deleted. Vector elements are stored in contiguous memory locations so that they can be accessed in constant time.
It is defined inside the <vector>
header file (also available in <bits/stdc++.h>
).
The complexity (efficiency) of common operations on vectors is as follows:
- Random access - constant π(1).
- Insertion or removal of elements at the end - amortized constant π(1).
- Insertion or removal of elements in front or middle of the vector π(n).
vector<int> vec;
Emptyvector<int> vec( size );
Vector with size 'size'vector<int> vec( size, value );
Vector with size 'size' and all elements with value 'value'vector<int> vec = { value1, value2, value3,...,valueN};
Vector with N values
vector<int> vec; // Declares an empty vector with name as vec ---> []
vector<int> vec(5); // Declares vector of ints with size 5 and the default values assigned are 0s ---> [0,0,0,0,0]
vector<int> vec(5, 10); // Declares vector of ints with size 5 and values assigned are 10s ---> [10,10,10,10,10]
vector<int> vec = {1, 2, 3, 4}; // Declares vector with size 4 and values as ---> [1, 2, 3, 4]
vector<string> vect(5) ; // Declares vector with 5 empty strings ---> ["", "", "", "", ""]
vector<string> vec(5, "Leetcode"); // Declares vector of strings with size 5 and values initialised are "Leetcode" ---> ["Leetcode", "Leetcode", "Leetcode", "Leetcode", "Leetcode"]
vector<vector<int>> vec(5); // Declares vector of vectors ---> [[], [], [], [], []]
vector<vector<int>> vec(5, vector<int>(2)); // Declares vector of vectors(here inside vector size is 2 and default values assigned are 0's) ---> [[0,0], [0,0], [0,0], [0,0], [0,0]]
vector<vector<int>> vec(5, vector<int>(2, 10)); // Declares vector of vectors(here inside vector size is 2 and default values assigned are 10's) ---> [[10,10], [10,10],[10,10],[10,10],[10,10]]
vec.push_back( ele );
Adds an element 'ele' at the end, and size of the vector increases by 1 (TC - π(1))vec.emplace_back( ele );
Adds an element 'ele' at the end, and size of the vector increases by 1 (TC - π(1))vec.insert( vec.begin() + i, ele );
Inserting element 'ele' at index i | Use i = 0 for inserting at the front (TC - π(n))vec.insert( vec.end(), vec2.begin(), vec2.end() );
Inserting the elements of vector 'v2' to the end of vector 'v' (TC - π(n))
v.pop_back();
Remove element at the end (TC - π(1))v.erase( v.begin() + i );
Remove element at index i or i = 0 to remove the first element (TC - π(n))v.erase( v.begin() + i, v.begin() + j );
Remove elements from index i to j-1 (TC - π(n))v.erase( remove( v.begin(), v.end(), value ), v.end() );
Removes all elements with value 'value' from the vector (TC - π(n))
v.size();
Returns the size of vector (TC - π(1))v.resize( size, val );
If the 'size' is greater than the previous size, then it adds elements with value 'val' at end and if 'size' is less than previous, then it removes from endv.empty();
Returns true if the vector is empty (TC - π(1))v.front();
orv[0];
Accessing the first element (TC - π(1))v.back();
orv[v.size()-1];
Accessing the last element (TC - π(1))v[i];
Accessing element at i'th index (0-based) (TC - π(1))v.at(i);
Accessing element at i'th index (0-based) (TC - π(1))v.clear();
Clears vector elements by making vector as empty (TC - π(n))
sort(v.begin(), v.end());
Sorts vector elements in ascending order by default (TC - π(nlogn))sort(v.begin(), v.end(), greater<int>);
Sorts vector elements in descending order (TC - π(nlogn))reverse(v.begin(), v.end());
Reverses vector elements (TC - π(n))count(v.begin(), v.end(), x);
Returns the count of x in vector (TC - π(n))min_element(v.begin(), v.end()) - v.begin();
Returns the minimum element's index (0-based) from the vector (TC - π(n))max_element(v.begin(), v.end()) - v.begin();
Returns the maximum element's index (0-based) from the vector (TC - π(n))*min_element(v.begin(), v.end());
Returns the minimum element from the vector (TC - π(n))*max_element(v.begin(), v.end());
Returns the maximum element from the vector (TC - π(n))
Note: The difference between v[i]
and v.at(i)
is that 'at' will raise an exception if you try to access an element outside the vector while the []
operator won't.
Lets undertand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> v = {1, 3, 2}; // Create a vector containing integers ---> [1, 3, 2]
// Insertion
v.push_back(5); // Adding 5 at the end ---> [1, 3, 2, 5]
v.emplace_back(4); // Adding 4 at the end ---> [1, 3, 2, 5, 4]
v.insert(v.begin(), 10); // Inserts 10 at the beginning ---> [10, 1, 3, 2, 5, 4]
v.insert(v.begin() + 3, 15); // Inserts 15 at 3rd index ---> [10, 1, 3, 15, 2, 5, 4]
// Deletion
v.pop_back(); // Removes an element at the end ---> [10, 1, 3, 15, 2, 5]
v.erase(v.begin()); // Removes an element at the front ---> [1, 3, 15, 2, 5]
v.erase(v.begin() + 3); // Removes an element at 3rd index ---> [1, 3, 15, 5]
// Accessing and Updating
int a = v[3]; // Here the variable a stores the value at 3rd index i.e., 5
v[1] = 100; // Here the value at index 1 is updated with 100 ---> [1, 100, 15, 5]
int last_element = v.back(); // i.e., 5
int first_element = v.front(); // i.e., 1
sort(v.begin(), v.end()); // Sorts vector elements ---> [1, 5, 15, 100]
reverse(v.begin(), v.end()); // Reverses vector elements ---> [100, 15, 5, 1]
// Traversing the vector using a for loop
for (int i = 0; i < v.size(); i++) {
cout << v[i] << " "; // After the for loop, Output is: 100 15 5 1
}
int length = v.size(); // Here the variable length stores the vector size i.e., 4
v.clear(); // Vector is cleared ---> []
bool isVectorEmpty = v.empty(); // Here the variable isVectorEmpty stores 'true' as the vector is empty
return 0;
}
- A stack is a linear data structure that follows the principle of
Last In First Out (LIFO)
. This means the last element inserted inside the stack is removed first. - It is defined inside
<stack>
header file (also available in<bits/stdc++.h>
).
stack< data_type > stack_name;
stack<int> stk;
stack of int'sstack<string> stk;
stack of stringsstack<pair<int, int>> stk;
stack of pairsstack<vector<int>> stck;
stack of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
stk.push(ele);
pushes an element 'ele' into the stack TC - π(1)stk.pop();
removes the top element TC - π(1)stk.top();
returns the topmost element TC - π(1)stk.size();
returns the size of stack TC - π(1)stk.empty();
returns true if the stack is empty else false TC - π(1)
Note: The time complexity of all above inbuilt functions is constant - π(1)
Since it won't provide indexing, we cannot directly access any element except the top element. The below is the way to traverse the stack.
while(!stk.empty()){
cout << stk.top() << " ";
stk.pop();
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
stack<string> stk;
//pushing data into the stack
stk.push("Hi");
stk.push("Hello");
stk.push("How are you?");
//poping data from top of the stack
stk.pop(); // the top element i.e "How are you?" is removed;
cout << stk.top() << " "; // prints top element "Hello"
cout << stk.size() << " "; // prints 2
cout << stk.empty(); //prints false | 0
return 0;
}
- A queue is a linear data structure that follows the
FIFO (First In First Out)
principle, i.e., elements that are added first will be removed first. - It is defined inside
<queue>
header file (also available in<bits/stdc++.h>
).
queue< data_type > queue_name;
queue<int> q;
queue of int'squeue<string> q;
queue of stringsqueue<pair<int, int>> q;
queue of pairsqueue<vector<int>> q;
queue of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
q.push(ele);
pushes an element 'ele' into the queue from the end TC - π(1)q.pop();
removes an element from the front of the queue TC - π(1)q.front();
returns the first element TC - π(1)q.back();
returns the last element TC - π(1)q.size();
returns the size of the queue TC - π(1)q.empty();
returns true if the queue is empty else false TC - π(1)
Note: The time complexity of all above inbuilt functions is constant - π(1)
Since it won't provide indexing, we cannot directly access any element except the first and last element. The below is the way to traverse the queue.
while(!q.empty()){
cout << q.front() << " ";
q.pop();
}
Let's understand with a sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
queue<string> q;
// Pushing data into the queue
q.push("Hi");
q.push("Hello");
q.push("How are you?");
// Popping data from the top of the queue
q.pop(); // The front element, i.e., "Hi", is removed;
cout << q.front() << " "; // Prints the front element, "Hello"
cout << q.back() << " "; // Prints the back element, "How are you?"
cout << q.size() << " "; // Prints 2
cout << q.empty(); // Prints false | 0
return 0;
}
Deque is an indexed sequence container that allows fast insertion and deletion at both its beginning and its end.
The complexity (efficiency) of common operations on deques is as follows:
- Random access - constant π(1)
- Insertion or removal of elements at the end or beginning - constant π(1)
- Insertion or removal of elements - linear π(n)
Formally, a deque supports all the functions that a vector supports. The difference between a deque and a vector is that deques do not guarantee that their elements are contiguous in memory, so accessing may not be as efficient.
deque< data_type > deque_name;
deque<int> dq;
Deque of int (Empty)deque<int> dq( size );
Deque with size 'size'deque<int> dq( size, value );
Deque with size 'size' and all elements with value 'value'deque<int> dq = { value1, value2, value3,...,valueN};
Deque with N values
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
dq.push_back( ele );
Adds an element 'ele' at the end (TC - π(1))dq.pop_back();
Removes an element at the end (TC - π(1))dq.push_front( ele );
Adds an element 'ele' at the front (TC - π(1))dq.pop_front();
Removes an element at the front (TC - π(1))dq.size();
Returns the size of the deque (TC - π(1))dq.empty();
Returns true if the deque is empty, else false (TC - π(1))dq.front();
ordq[0];
Accesses the first element (TC - π(1))dq.back();
ordq[dq.size()-1];
Accesses the last element (TC - π(1))dq[i];
Accesses the element at the i'th index (0-based) (TC - π(1))dq.at(i);
Accesses the element at the i'th index (0-based) (TC - π(1))
- A priority queue is a special type of queue in which each element is associated with a priority value, and elements are served based on their priority.
- It is defined inside the
<queue>
header file (also available in<bits/stdc++.h>
). - By default, C++ creates a max priority queue. We can change it to a min priority queue by passing additional parameters during declaration.
priority_queue< data_type > priority_queue_name;
priority_queue< data_type, vector< data_type >, greater< data_type > > priority_queue_name;
priority_queue<int> q; // max priority_queue of int's
priority_queue<string> q; // max priority_queue of strings
priority_queue<pair<int, int>> q; // max priority_queue of pairs
priority_queue<vector<int>> q; // max priority_queue of vectors
priority_queue<int, vector<int>, greater<int>> q; // min priority_queue of int's
priority_queue<string, vector<string>, greater<string>> q; // min priority_queue of strings
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; // min priority_queue of pairs
priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> q; // min priority_queue of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
pq.push(ele);
Inserts the element 'ele' into the priority queue. [Time Complexity: π(logn)]pq.pop();
Removes the element with the highest priority. [Time Complexity: π(logn)]pq.top();
Returns the element with the highest priority. [Time Complexity: π(1)]pq.size();
Returns the size of the priority_queue. [Time Complexity: π(1)]pq.empty();
Returns true if the priority_queue is empty, else false. [Time Complexity: π(1)]
Since it won't provide indexing, we cannot directly access any element except the top element. The below is the way to traverse the priority_queue.
while (!pq.empty()) {
cout << pq.top() << " ";
pq.pop();
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
priority_queue<int> pq;
// Pushing data into the priority_queue
pq.push(6);
pq.push(10);
pq.push(0);
pq.push(-40);
pq.push(8);
pq.push(-20);
pq.push(3);
cout << pq.top() << " "; // Prints the top element, i.e., 10
// Popping data from the top of the queue
pq.pop(); // The top element, i.e., 10, is removed;
cout << pq.top() << " "; // Prints the current top element, i.e., 8
cout << pq.size() << " "; // Prints 6
cout << pq.empty(); // Prints false | 0
return 0;
}
- A set data structure
won't allow duplicate keys
. - Keys are sorted in ascending order by default. We can also change the order by passing extra arguments during its declaration.
- Implemented using
Binary search tree
(Red-Black trees).
set< data_type > st; stores keys in ascending order
set< data_type, greater< data_type > > st; stores keys in descending order
set<int> st;
set of int'sset<string> st;
set of stringsset<pair<int, int>> st;
set of pairsset<vector<int>> st;
set of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
st.insert( key );
Inserts the element into the set (if not present). TC - π(logn)st.erase( key );
Removes the specified key if present. TC - π(logn)st.find( key );
Returns an iterator pointing to the key; if the key is not present, returns st.end(). TC - π(logn)st.size();
Returns the size of the set. TC - π(1)st.empty();
Returns true if the set is empty, else false. TC - π(1)st.clear();
Removes all set elements. TC - π(n)
Since it won't provide indexing, we cannot directly access any element. The below is the way to traverse the set.
for (auto x : st) {
cout << x << " "; // Prints each key in ascending order
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
set<int> st;
// Inserting data into the set
st.insert(1); // Inserts 1 into the set
st.insert(1); // Since 1 is already present, it won't insert 1 again into the set
st.insert(5); // Inserts 5 into the set
st.insert(10); // Inserts 10 into the set
st.insert(15); // Inserts 15 into the set
st.insert(5); // Since 5 is already present, it won't insert 5 again into the set
if (st.find(100) != st.end()) {
cout << "Key is present ";
} else {
cout << "Key is not present "; // Prints "Key is not present"
}
if (st.find(1) != st.end()) {
cout << "Key is present "; // Prints "Key is present" since 1 is present in the set
} else {
cout << "Key is not present ";
}
st.erase(1); // Removes 1 from the set
cout << st.size() << " "; // Prints 3
cout << st.empty(); // Prints false | 0
st.clear(); // Removes all elements.
return 0;
}
- An
unordered_set
is similar to the set data structure and won't allow duplicate keys. - The keys are
not sorted
in any order (No order), and hence the ordering of elements cannot be expected. - It is implemented using
Hash Tables
. - Faster in insertion / removal / find than set in average case i.e TC - O(1). ( worst case TC - O(n))
unordered_set< data_type > st;
unordered_set<int> st;
unordered_set of int'sunordered_set<string> st;
unordered_set of stringsunordered_set<pair<int, int>> st;
unordered_set of pairsunordered_set<vector<int>> st;
unordered_set of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
-
st.insert(key);
- Inserts the element 'key' into the set (if not present).
- Average Time Complexity: π(1)
- Worst Time Complexity: O(n)
-
st.erase(key);
- Removes the specified key if present.
- Average Time Complexity: π(1)
- Worst Time Complexity: O(n)
-
st.find(key);
- Returns an iterator pointing to the key. If the key is not present, returns
st.end()
. - Average Time Complexity: π(1)
- Worst Time Complexity: O(n)
- Returns an iterator pointing to the key. If the key is not present, returns
-
st.size();
- Returns the size of the set.
- Time Complexity: π(1)
-
st.empty();
- Returns true if the set is empty, else false.
- Time Complexity: π(1)
-
st.clear();
- Removes all set elements.
- Time Complexity: O(n)
Since it won't provide indexing, we cannot directly access any element. The below is the way to traverse the unordered_set.
for (auto x : st) {
cout << x << " "; // prints each key in ascending order
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
unordered_set<int> st;
// Inserting data into the set
st.insert(1); // Inserts 1 into set
st.insert(1); // Since 1 is already present, it won't insert 1 again into set
st.insert(5); // Inserts 5 into set
st.insert(10); // Inserts 10 into set
st.insert(15); // Inserts 15 into set
st.insert(5); // Since 5 is already present, it won't insert 5 again into set
if (st.find(100) != st.end()) {
cout << " Key is present ";
} else {
cout << " Key is not present "; // Prints "Key is not present"
}
if (st.find(1) != st.end()) {
cout << " Key is present "; // Prints "Key is present" since 1 is present in set
} else {
cout << " Key is not present ";
}
st.erase(1); // 1 removed from set
cout << st.size() << " "; // Prints 3
cout << st.empty(); // Prints false | 0
st.clear(); // Removes all elements.
return 0;
}
- A multiset data structure
allows multiple keys with the same values
. - Keys are sorted in ascending order by default. We can also change the order by passing extra arguments during its declaration.
- Implemented using
Binary search tree
(Red-black trees).
multiset< data_type > st; Stores keys in ascending order
multiset< data_type, greater< data_type > > st; Stores keys in descending order
multiset<int> st;
Multiset of int'smultiset<string> st;
Multiset of stringsmultiset<pair<int, int>> st;
Multiset of pairsmultiset<vector<int>> st;
Multiset of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
st.insert( key );
Inserts the element into the multiset. TC - π(logn)st.erase( key );
Removes all occurrences of the specified key if present. TC - π(logn)st.erase( st.find( key ) );
Removes only one occurrence of the specified key if present. TC - π(logn)st.find( key );
Returns an iterator pointing to the key; if the key is not present, returnsst.end()
. TC - π(logn)st.count( key );
Returns the frequency of the specified key. TC - π(logn)st.size();
Returns the size of the multiset. TC - π(1)st.empty();
Returns true if the multiset is empty; else, false. TC - π(1)st.clear();
Removes all multiset elements. TC - O(n)
Since it won't provide indexing, we cannot directly access any element. The below is the way to traverse the multiset.
for( auto x : st ){
cout << x << " "; // Prints each key in ascending order
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
multiset<int> st;
// Inserting data into the multiset
st.insert(1); // Inserts 1 into the multiset
st.insert(1); // Inserts 1 into the multiset
st.insert(1); // Inserts 1 into the multiset
st.insert(5); // Inserts 5 into the multiset
st.insert(10); // Inserts 10 into the multiset
st.insert(15); // Inserts 15 into the multiset
st.insert(5); // Inserts 5 into the multiset
if( st.find(100) != st.end()){
cout << " Key is present " << " ";
}
else {
cout << " Key is not present "; // Prints key is not present
}
if( st.find(1) != st.end()){
cout << " Key is present " << ; // Prints key is present since 1 is present in the multiset
}
else {
cout << " Key is not present ";
}
cout << st.count( 1 ) ; // Prints 3
st.erase( st.find(1) ); // Removes one occurrence of 1
cout << st.count(1) ; // Prints 2
st.erase( 1 ); // Removes all occurrences of 1
cout << st.count(1) ; // Prints 0
cout << st.size() << " "; // Prints 4
cout << st.empty(); // Prints false | 0
st.clear(); // Removes all elements.
return 0;
}
- An
unordered_multiset
data structure allows multiple keys with the same values. - Keys are
not sorted
, i.e., there is no particular order. - Implemented using
Hash Tables
.
unordered_multiset< data_type > st;
unordered_multiset<int> st;
unordered_multiset of int'sunordered_multiset<string> st;
unordered_multiset of stringsunordered_multiset<pair<int, int>> st;
unordered_multiset of pairsunordered_multiset<vector<int>> st;
unordered_multiset of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
-
st.insert( key );
- Inserts the element into the multiset.
- Average Time Complexity: π(1)
- Worst Time Complexity: π(n)
-
st.erase( key );
- Removes all occurrences of the specified key if present.
- Average Time Complexity: π(1)
- Worst Time Complexity: π(n)
-
st.erase( st.find( key ) );
- Removes only one occurrence of the specified key if present.
- Average Time Complexity: π(1)
- Worst Time Complexity: π(n)
-
st.find( key );
- Returns an iterator pointing to the key. If the key is not present, returns
st.end()
. - Average Time Complexity: π(1)
- Worst Time Complexity: π(n)
- Returns an iterator pointing to the key. If the key is not present, returns
-
st.count( key ) ;
- Returns the frequency of the specified key.
- Average Time Complexity: π(1)
- Worst Time Complexity: π(n)
-
st.size();
- Returns the size of the multiset.
- Time Complexity: π(1)
-
st.empty();
- Returns true if the multiset is empty, else false.
- Time Complexity: π(1)
-
st.clear();
- Removes all multiset elements.
- Time Complexity: π(n)
Since it doesn't provide indexing, we cannot directly access any element. You can traverse the multiset using the following loop:
for (auto x : st) {
cout << x << " "; // prints each key in ascending order
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
unordered_multiset<int> st;
// Inserting data into the multiset
st.insert(1); // inserts 1 into multiset
st.insert(1); // inserts 1 into multiset
st.insert(1); // inserts 1 into multiset
st.insert(5); // inserts 5 into multiset
st.insert(10); // inserts 10 into multiset
st.insert(15); // inserts 15 into multiset
st.insert(5); // inserts 5 into multiset
// Checking if 100 is present in the multiset
if (st.find(100) != st.end()) {
cout << "Key is present ";
} else {
cout << "Key is not present "; // prints key is not present
}
// Checking if 1 is present in the multiset
if (st.find(1) != st.end()) {
cout << "Key is present ";
} else {
cout << "Key is not present ";
}
// Counting occurrences of 1 in the multiset
cout << st.count(1); // prints 3
// Removing one occurrence of 1 from the multiset
st.erase(st.find(1));
// Counting occurrences of 1 in the multiset after removal
cout << st.count(1); // prints 2
// Removing all occurrences of 1 from the multiset
st.erase(1);
// Counting occurrences of 1 in the multiset after removal
cout << st.count(1); // prints 0
// Printing the size of the multiset
cout << st.size() << " "; // prints 4
// Printing whether the multiset is empty or not
cout << st.empty(); // prints false | 0
// Removing all elements from the multiset
st.clear(); // removes all elements.
return 0;
}
- A map is a data structure that stores elements in a mapped fashion. Each element has a key value and a mapped value, effectively storing
key-value pairs
. - Keys are unique and sorted in ascending order by default.
- Implemented using
Binary Search Trees
(Red-Black Trees).
map<key_data_type, value_data_type> mp; keys are unique and sorted in ASC
map<int, int> mp;
map of int as key and int as valuemap<int, string> mp;
map of int as key and String as valuemap<int, vector<int>> mp;
map of int as key and vector as valuemap<string, vector<int>> mp;
map of String as key and vector as value
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
-
mp[key] = value;
Inserts key-value pair if not present. If present, updates the key with the current value.
TC - O(logn) -
int a = mp[key];
Returns the value at the specified key. If key is not present, it returns the default value and adds key->default_value into the map.
TC - O(logn) -
mp.insert({key, value});
Inserts a new key-value pair if the key is not present. If present, it won't add this key-value pair and won't update. -
mp.insert(make_pair(key, value));
Inserts a new key-value pair if the key is not present. If present, it won't add this key-value pair and won't update. -
mp.insert(pair<int, int>(5, 7));
Inserts a new key-value pair if the key is not present. If present, it won't add this key-value pair and won't update. -
mp.erase(key);
Removes the specified entry with the specified key if present.
TC - O(logn) -
mp.count(key);
Returns the frequency of the key (0 or 1).
TC - O(logn) -
mp.find(key);
Returns the iterator pointing to the key if present, else returns mp.end().
TC - O(logn) -
mp.clear();
Removes all entries from the map.
TC - O(n) -
mp.size();
Returns the size of the map.
TC - O(1) -
mp.empty();
Returns true if the map is empty, else false.
TC - O(1)
for(auto ele : mp){
cout << ele.first << " " << ele.second << "\n";
}
for(auto it = mp.begin() ; it != mp.end() ; it++){
cout << it->first << " " << it->second << "\n";
}
for(auto it = mp.rbegin() ; it != mp.rend() ; it++){
cout << it->first << " " << it->second << "\n";
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
map<int, int> mp; // creates an empty map ---> []
mp[5] = 10; // since key = 5 is not present, adds the entry with key as 5 and value as 10 ---> [5->10]
mp[5] = 9; // key = 5 is present hence it updates with current value ---> [5->9]
mp.insert(pair<int, int>(3, 7)); // since key = 3 is not present, adds the entry 3->7 ----> [3->7, 5->9]
mp.insert(pair<int, int>(5, 8)); // since key = 5 is present, it won't add and update the entry. ---> [3->7, 5->9]
mp.insert(make_pair(8, 1)); // since key = 8 is not present, adds the entry 8->1 ----> [3->7, 5->9, 8->1]
mp.insert(make_pair(8, 2)); // since key = 8 is present, it won't add and update the entry. ---> [3->7, 5->9, 8->1]
mp.insert({6, 11}); // since key = 6 is not present, adds the entry 6->11 ----> [3->7, 5->9, 6->11, 8->1]
mp.insert({6, 99}); // since key = 6 is present, it won't add and update the entry. ---> [3->7, 5->9, 6->11, 8->1]
cout << "size is " << mp.size() << "\n"; // prints 4
mp.erase(5); // removes entry whose key = 5 i.e 5->9. ---> [3->7, 6->11, 8->1]
mp.erase(100); // removes entry whose key = 100, but there is no entry matching this. So nothing will happen. ---> [3->7, 6->11, 8->1]
cout << "value at key = 8 is " << mp[8] << "\n"; // prints the value at key = 8 i.e 1
cout << "value at key = 99 is " << mp[99] << "\n"; // since there is no key = 99 it adds entry 99->0 (0 is the default value) and prints 0. ---> [3->7, 6->11, 8->1, 99->0]
cout << "Frequency of entry whose key = 3 is " << mp.count(3) << "\n";
if (mp.find(12) != mp.end())
cout << "Key = 12 is present \n";
else
cout << "key = 12 is not present\n";
if (mp.find(99) != mp.end())
cout << "Key = 99 is present \n";
else
cout << "key = 99 is not present\n";
// printing map
cout << "map entries are: \n";
for (auto it = mp.begin(); it != mp.end(); it++) {
cout << it->first << "->" << it->second << "\n";
}
return 0;
}
- An
unordered_map
is a data structure that stores elements in a mapped fashion. Each element has a key value and a mapped value. Essentially, it stores key-value pairs. - Keys are unique and do not have a particular order.
- Implemented using
Hash tables
.
unordered_map<key_data_type, value_data_type> mp; // keys are unique and not have a particular order
unordered_map<int, int> mp;
unordered_map of int as key and int as valueunordered_map<int, string> mp;
unordered_map of int as key and String as valueunordered_map<int, vector<int>> mp;
unordered_map of int as key and vector as valueunordered_map<string, vector<int>> mp;
unordered_map of String as key and vector as value
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
-
mp[key] = value;
Inserts key->value pair if not present. If present, updates the key with the current value.- Average TC: O(1)
- Worst TC: O(n)
-
int a = mp[key];
Returns the value at the specified key. If the key is not present, it returns the default value and adds key->default_value into the map.- Average TC: O(1)
- Worst TC: O(n)
-
mp.insert(make_pair(key, value));
Inserts a new key-value pair if the key is not present. If present, it won't add this key-value pair and won't update.- Average TC: O(1)
- Worst TC: O(n)
-
mp.insert({key, value});
Inserts a new key-value pair if the key is not present. If present, it won't add this key-value pair and won't update.- Average TC: O(1)
- Worst TC: O(n)
-
mp.insert(pair<int, int>(5, 7));
Inserts a new key-value pair if the key is not present. If present, it won't add this key-value pair and won't update.- Average TC: O(1)
- Worst TC: O(n)
-
mp.erase(key);
Removes the specified entry with the specified key if present.- Average TC: O(1)
- Worst TC: O(n)
-
mp.count(key);
Returns the frequency of the key (0 or 1).- Average TC: O(1)
- Worst TC: O(n)
-
mp.find(key);
Returns the position of the key if present, else returnsmp.end()
.- Average TC: O(1)
- Worst TC: O(n)
-
mp.clear();
Removes all entries from the map.- TC: O(n)
-
mp.size();
Returns the size of the map.- TC: O(1)
-
mp.empty();
Returns true if the map is empty, else false.- TC: π(1)
for(auto ele : mp){
cout << ele.first << " " << ele.second << "\n";
}
for(auto it = mp.begin() ; it != mp.end() ; it++){
cout << it->first << " " << it->second << "\n";
}
for(auto it = mp.rbegin() ; it != mp.rend() ; it++){
cout << it->first << " " << it->second << "\n";
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
unordered_map<int, int> mp; // creates an empty map ---> []
mp[5] = 10; // since key = 5 is not present, adds the entry with key as 5 and value as 10 ---> [5->10]
mp[5] = 9; // key = 5 is present hence it updates with the current value ---> [5->9]
mp.insert(pair<int, int>(3, 7)); // since k = 3 is not present adds the entry 3->7 ----> [5->9, 3->7] (Note: order is not guaranteed)
mp.insert(pair<int, int>(5, 8)); // since key = 5 is present it won't add and update the entry. ---> [3->7, 5->9] (Note: order is not guaranteed)
mp.insert(make_pair(8, 1)); // since key = 8 is not present adds the entry 8->1 ----> [3->7, 5->9, 8->1] (Note: order is not guaranteed)
mp.insert(make_pair(8, 2)); // since key = 8 is present it won't add and update the entry. ---> [3->7, 5->9, 8->1] (Note: order is not guaranteed)
mp.insert({6, 11}); // since key = 6 is not present adds the entry 6->11 ----> [3->7, 5->9, 6->11, 8->1] (Note: order is not guaranteed)
mp.insert({6, 99}); // since key = 6 is present it won't add and update the entry. ---> [6->11, 8->1, 5->9, 3->7] (Note: order is not guaranteed)
cout << "size is " << mp.size() << "\n"; // prints 4
mp.erase(5); // removes entry whose key = 5 i.e 5->9. ---> [3->7, 8->1, 6->11] (Note: order is not guaranteed)
mp.erase(100); // removes entry whose key = 100, but there is no entry matching this. So nothing will happen. ---> [3->7, 6->11, 8->1] (Note: order is not guaranteed)
cout << "value at key = 8 is " << mp[8] << "\n"; // prints the value at key = 8 i.e 1
cout << "value at key = 99 is " << mp[99] << "\n"; // since there is no key = 99 it adds entry 99->0 (0 is the default value) and prints 0. ---> [3->7, 6->11, 8->1, 99->0] (Note: order is not guaranteed)
cout << "Frequency of entry whose key = 3 is " << mp.count(3) << "\n";
if(mp.find(12) != mp.end()) cout << "Key = 12 is present \n";
else cout << "key = 12 is not present\n";
if(mp.find(99) != mp.end()) cout << "Key = 99 is present \n";
else cout << "key = 99 is not present\n";
// printing map
cout << "map entries are: \n" ;
for(auto it = mp.begin() ; it != mp.end() ; it++){
cout << it->first << "->" << it->second << "\n";
}
return 0;
}
- A
multimap
is a data structure that stores elements in a mapped fashion. Each element has a key value and a mapped value, essentially storing key-value pairs. - The multimap is similar to a map, with the addition that multiple elements can have the same keys.
- Keys are sorted in ascending order by default.
- Implemented using
Binary Search Trees
(Red-Black Trees).
multimap<key_data_type, value_data_type> mp; // keys are sorted in ascending order
multimap<int, int> mp;
multimap of int'smultimap<int, string> mp;
multimap of stringsmultimap<int, vector<int>> mp;
multimap of vectorsmultimap<string, vector<int>> mp;
multimap of vectors
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
mp.insert(make_pair(key, value)); // inserts new key-value pair TC - O(logn)
mp.insert({key, value}); // inserts new key-value pair TC - O(logn)
mp.insert(pair<int, int>(5, 7)); // inserts new key-value pair TC - O(logn)
mp.erase(key); // removes all occurrences of entries with specified key if present. TC - O(logn)
mp.erase(mp.find(key)); // removes one occurrence of entry with specified key if present. TC - O(logn)
mp.count(key); // returns frequency of key TC - O(logn)
mp.find(key); // returns pos of key if present. else return mp.end() TC - O(logn)
mp.clear(); // removes all entries from the map TC - O(n)
mp.size(); // returns the size of map TC - O(1)
mp.empty(); // returns true if map is empty else false TC - π(1)
for(auto ele : mp){
cout << ele.first << " " << ele.second << "\n";
}
for(auto it = mp.begin(); it != mp.end(); it++){
cout << it->first << " " << it->second << "\n";
}
for(auto it = mp.rbegin(); it != mp.rend(); it++){
cout << it->first << " " << it->second << "\n";
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
multimap<int, int> mp; // creates an empty map ---> []
mp.insert(pair<int, int>(3, 7)); // adds the entry 3->7 ----> [3->7]
mp.insert(pair<int, int>(5, 8)); // adds the entry 5->8---> [3->7, 5->8]
mp.insert(make_pair(8, 1)); // adds the entry 8->1.---> [3->7, 5->8, 8->1]
mp.insert(make_pair(8, 2)); // adds the entry 8->2.---> [3->7, 5->8, 8->1, 8->2]
mp.insert({6, 11}); // adds the entry 6->11.---> [3->7, 5->8, 6->11, 8->1, 8->2]
mp.insert({6, 99}); // adds the entry 6->11.---> [3->7, 5->8, 6->11, 6->99, 8->1, 8->2]
mp.insert({6, 15}); // adds the entry 6->15.---> [3->7, 5->8, 6->11, 6->99, 6->15, 8->1, 8->2]
cout << "size is " << mp.size() << "\n"; // prints 7
cout << "Frequency of entry whose key = 6 is " << mp.count(6) << "\n";
auto it = mp.begin();
while(it != mp.end()){
if(it->first == 6 && it->second == 11) break;
it++;
}
mp.erase(it); // removes entry that 'it' points i.e 6->11. ---> [3->7, 5->8, 6->99, 6->15, 8->1, 8->2]
cout << "Frequency of entry whose key = 6 after removing one occurrence is " << mp.count(6) << "\n";
mp.erase(6); // removes all occurrences of entry's whose keys = 6 ---> [3->7, 5->8, 8->1, 8->2]
cout << "Frequency of entry whose key = 6 after removing all occurrences is " << mp.count(6) << "\n";
mp.erase(100); // since there is no key = 100, nothing will be removed ---> [3->7, 5->8, 8->1, 8->2]
if(mp.find(12) != mp.end()) cout << "Key = 12 is present \n";
else cout << "key = 12 is not present\n";
if(mp.find(8) != mp.end()) cout << "Key = 8 is present \n";
else cout << "key = 99 is not present\n";
// printing map
cout << "map entry's are: \n" ;
for(auto it = mp.begin() ; it != mp.end() ; it++){
cout << it->first << "->" << it->second << "\n";
}
return 0;
}
- An
unordered_multimap
is a data structure that stores elements in a mapped fashion. Each element has a key value and mapped value, essentially storing key-value pairs. - Multimap is similar to a map with the addition that
multiple elements can have the same keys
. - Keys in an
unordered_multimap
are not sorted, meaning there is no particular order. - Implemented using
Hash Tables
.
unordered_multimap<key_data_type, value_data_type> mp; // keys are not sorted i.e no particular order
unordered_multimap<int, int> mp;
unordered_multimap of int as key and int as valueunordered_multimap<int, string> mp;
unordered_multimap of int as key and String as valueunordered_multimap<int, vector<int>> mp;
unordered_multimap of int as key and vector as valueunordered_multimap<string, vector<int>> mp;
unordered_multimap of String as key and vector as value
Note: Similar syntax for char
, long long int
, float
, double
, long double
, and some other data types, including user-defined data types.
-
mp.insert(make_pair(key, value));
Inserts a new key-value pair.- Average Time Complexity: O(1)
- Worst Time Complexity: O(n)
-
mp.insert({key, value});
Inserts a new key-value pair.- Average Time Complexity: O(1)
- Worst Time Complexity: O(n)
-
mp.insert(pair<int, int>(5, 7));
Inserts a new key-value pair.- Average Time Complexity: O(1)
- Worst Time Complexity: O(n)
-
mp.erase(key);
Removes all occurrences of entries with the specified key if present.- Average Time Complexity: O(1)
- Worst Time Complexity: O(n)
-
mp.erase(mp.find(key));
Removes one occurrence of the entry with the specified key if present.- Average Time Complexity: O(1)
- Worst Time Complexity: O(n)
-
mp.count(key);
Returns the frequency of the key.- Average Time Complexity: O(1)
- Worst Time Complexity: O(n)
-
mp.find(key);
Returns the position of the key if present, otherwise returnsmp.end()
.- Average Time Complexity: O(1)
- Worst Time Complexity: O(n)
-
mp.clear();
Removes all entries from the map.- Time Complexity: O(n)
-
mp.size();
Returns the size of the map.- Time Complexity: O(1)
-
mp.empty();
Returns true if the map is empty; otherwise, false.- Time Complexity: π(1)
for(auto ele : mp){
cout << ele.first << " " << ele.second << "\n";
}
for(auto it = mp.begin() ; it != mp.end() ; it++){
cout << it->first << " " << it->second << "\n";
}
for(auto it = mp.rbegin() ; it != mp.rend() ; it++){
cout << it->first << " " << it->second << "\n";
}
Lets understand by sample program
#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
unordered_multimap<int, int> mp; // creates an empty map ---> []
mp.insert(pair<int, int>(3, 7)); // adds the entry 3->7 ----> [3->7] (Note: Order of elements is not expected)
mp.insert(pair<int, int>(5, 8)); // adds the entry 5->8---> [3->7, 5->8] (Note: Order of elements is not expected)
mp.insert(make_pair(8, 1)); // adds the entry 8->1.---> [3->7, 5->8, 8->1] (Note: Order of elements is not expected)
mp.insert(make_pair(8, 2)); // adds the entry 8->2.---> [3->7, 5->8, 8->1, 8->2] (Note: Order of elements is not expected)
mp.insert({6, 11}); // adds the entry 6->11.---> [3->7, 5->8, 6->11, 8->1, 8->2] (Note: Order of elements is not expected)
mp.insert({6, 99}); // adds the entry 6->11.---> [3->7, 5->8, 6->11, 6->99, 8->1, 8->2] (Note: Order of elements is not expected)
mp.insert({6, 15}); // adds the entry 6->15.---> [3->7, 5->8, 6->11, 6->99, 6->15, 8->1, 8->2] (Note: Order of elements is not expected)
cout << "size is " << mp.size() << "\n"; // prints 7
cout << "Frequency of entry whose key = 6 is " << mp.count(6) << "\n";
auto it = mp.begin();
while(it != mp.end()){
if(it->second == 11) break;
it++;
}
mp.erase(it); // removes the entry that 'it' points i.e 6->11. ---> [3->7, 5->8, 6->99, 6->15, 8->1, 8->2]
cout << "Frequency of entry whose key = 6 after removing one occurrence is " << mp.count(6) << "\n";
mp.erase(6); // removes all occurrences of entries whose keys = 6 ---> [3->7, 5->8, 8->1, 8->2]
cout << "Frequency of entry whose key = 6 after removing all occurrences is " << mp.count(6) << "\n";
mp.erase(100); // since there is no key = 100, nothing will be removed ---> [3->7, 5->8, 8->1, 8->2]
if(mp.find(12) != mp.end()) cout << "Key = 12 is present \n";
else cout << "key = 12 is not present\n";
if(mp.find(8) != mp.end()) cout << "Key = 8 is present \n";
else cout << "key = 99 is not present\n";
// printing map
cout << "map entry's are: \n" ;
for(auto it = mp.begin() ; it != mp.end() ; it++){
cout << it->first << "->" << it->second << "\n";
}
return 0;
}