Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on Hash
  • Practice Hash
  • MCQs on Hash
  • Hashing Tutorial
  • Hash Function
  • Index Mapping
  • Collision Resolution
  • Open Addressing
  • Separate Chaining
  • Quadratic probing
  • Double Hashing
  • Load Factor and Rehashing
  • Advantage & Disadvantage
Open In App
Next Article:
Queue for Competitive Programming
Next article icon

Hashing in Competitive Programming

Last Updated : 26 Mar, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Hashing is a fundamental technique in competitive programming that is used to efficiently manipulate and process large amounts of data. Data Structures like Hash Maps and Hash Sets use hashing techniques to provide faster insertion, deletion and retrieval of values.

Table of Content

  • What is Hashing?
  • Why use Hashing in Competitive Programming?
  • Advantages of Hashing
  • Disadvantages of Hashing
  • Common Hash Functions and Collision Handling Techniques
  • Use Cases of Hashing in Competitive Programming
  • Hashing in Competitive Programming for C++ Programmers
  • Hashing in Competitive Programming for Java Programmers
  • Hashing in Competitive Programming for Python Programmers
  • Practice Problems on Hashing for Competitive Programming

What is Hashing?

Hashing is a fundamental data structure and technique used in competitive programming to efficiently store and retrieve elements based on their "keys."

Imagine a filing cabinet with labels for each document. The labels are like hash functions, and the documents themselves are the elements. By using a good hash function, you can quickly find the document you need without having to look through every single one.

In computer science, hashing involves:

  • Hash function: This function takes an element as input and generates a fixed-size, unique value (hash code) for it. Ideally, different elements should have different hash codes (no collisions).
  • Hash table: This data structure stores the elements along with their hash codes. It allows for fast lookup and insertion based on the hash code.

Why use Hashing in Competitive Programming?

Competitive programming often involves dealing with large amounts of data and solving problems under tight time constraints. Hashing comes in handy in several situations:

  • Efficient searching: Finding specific elements in a large dataset becomes much faster with hashing compared to linear search (O(1) vs. O(n)).
  • Duplicate detection: Identifying duplicate elements becomes trivial with a good hash function.
  • Set operations: Operations like union, intersection, and difference on sets can be implemented efficiently using hashing.
  • Memory optimization: Hash tables can be more memory-efficient than other data structures like sorted arrays.
  • Solving specific problems: Certain problems in competitive programming, like string matching or finding collisions in data streams, have elegant solutions using hashing techniques.

Advantages of Hashing

  • Fast lookup and insertion: O(1) time complexity in the average case.
  • Memory efficiency: Can be more efficient than other data structures for certain types of data.
  • Simple to implement: Most languages provide built-in hash table libraries.

Disadvantages of Hashing

  • Collisions: Different elements can have the same hash code, requiring collision handling techniques (e.g., chaining, double hashing) which can impact performance.
  • Not a good fit for all problems: Not suitable for problems requiring frequent updates or deletions.
  • Choosing the right hash function: Important to select a good hash function to minimize collisions.

Common Hash Functions and Collision Handling Techniques

Several hash functions exist, each with its own strengths and weaknesses. Some popular choices include:

  • Modulo function: Hash code is the remainder of dividing the element's value by a prime number. Simple but can lead to collisions for certain data types.
  • Polynomial rolling hash: Used for string hashing. Efficiently calculates the hash for any substring based on the previous substring's hash.
  • MurmurHash family: High-performance hash functions with good collision resistance.

Collision handling techniques are crucial when different elements have the same hash code:

  • Open addressing: Re-inserts the element in another location in the hash table (e.g., linear probing, quadratic probing). Can lead to performance degradation if collisions are frequent.
  • Chaining: Stores elements with the same hash code in a linked list attached to the corresponding slot in the hash table. More efficient than open addressing for high collision rates.

Use Cases of Hashing in Competitive Programming

In competitive programming, hashing is a versatile technique for organizing and retrieving data. Because it performs lightning-quick lookups and data manipulation efficiently, it is a great tool for tackling algorithms. Here are some of its use cases/applications of hashing:

1. Finding Duplicate Elements:

Imagine a dataset where you need to identify duplicate elements. Brute-force pairwise comparisons are inefficient for large datasets. Hashing comes to the rescue. By mapping each element to a unique hash value in a hash table, finding duplicates becomes a simple lookup operation. Time complexity drops from O(n²) to O(1) on average, a significant improvement.

2. Implementing Disjoint-Set Union (DSU):

Disjoint-set union (DSU) algorithms manage groups of elements and perform operations like finding the representative of a group and merging groups. Hashing can be used to efficiently implement DSU by storing sets as hash tables. Finding the representative becomes a constant-time lookup, and merging sets involves updating the hash table pointers, keeping the operation efficient.

3. Counting Frequencies of Elements:

Counting the occurrences of each element in a dataset is another common task. Hashing offers a fast and memory-efficient solution. By storing element counts as values in a hash table, you can retrieve the frequency of any element with a single lookup. This approach is significantly faster than iterating through the entire dataset for each query.

4. Efficient String Matching:

String matching algorithms find occurrences of a pattern string within a larger text string. Hashing can significantly speed up this process. Algorithms like Rabin-Karp use rolling hashes to efficiently compute and compare hash values of substrings, potentially avoiding unnecessary character-by-character comparisons.

5. Solving Collision Problems:

Hash collisions occur when different elements map to the same hash value. While hash functions strive to minimize collisions, they are inevitable. Several techniques address this issue, including open addressing (probing for empty slots) and chaining (grouping colliding elements). Choosing the right approach depends on the specific scenario and desired trade-offs between speed and memory usage.

Hashing in Competitive Programming for C++ Programmers:

Initially, C++ had set and map, which are tree data structures which offers the worst-case time complexity of O(logN) to find any item. With C++11, hash set and hash map as unordered_set and unordered_map was introduced which offer an average case of O(1) but worst case of O(N) to insert, delete or retrieve any item. The average case is O(1) because it is assumed that each item only runs into O(1) collisions on average. For random input, they offer O(1) but it is possible to design inputs to make large number of collisions causing the time complexity of every operation to be O(N). This is quite common on various Competitive Programming platforms where people hack solutions of others who have used unordered maps with standard hash function assuming that it takes O(1) to perform every operation.

How to handle collision attacks?

It is clear that if we use unordered map with standard hash function, it is possible to break the solution from O(N) to O(N^2). The unordered_map class in C++ uses a combination of hashing and modulo arithmetic to store its elements. The hashing function is used to generate a hash value for each element, and the modulo arithmetic is used to map the hash value to a bucket in the hash table.

The __detail::_Mod_range_hashing class is responsible for implementing the modulo arithmetic part of the hashing process. This class takes a hash value as input and returns a bucket index. The __detail::_Prime_rehash_policy class is responsible for implementing the resizing policy of the hash table. This class determines when the hash table needs to be resized and how to resize it. The __prime_list array is an array of prime numbers that is used by the __detail::_Prime_rehash_policy class to determine the size of the hash table. When the hash table needs to be resized, the __detail::_Prime_rehash_policy class will choose the next prime number in the __prime_list array and resize the hash table to that size.

So, instead of using the standard hash function (identity function for integers), we can use a custom non-deterministic hash function that depends on time so even for the same inputs it produces different output.

Below is safe custom hash function that uses a high-precision clock to generate a random number that is used as input to the hash function. This makes it much more difficult for an attacker to predict the output of the hash function therefore making the time complexity of insert, delete and retrieve operations as O(1).

C++
#include <bits/stdc++.h> using namespace std;  struct gfg_custom_hash {     static uint64_t splitmix64(uint64_t key)     {         key += 0x9e3779b97f4a7c15;         key = (key ^ (key >> 30)) * 0xbf58476d1ce4e5b9;         key = (key ^ (key >> 27)) * 0x94d049bb133111eb;         return key ^ (key >> 31);     }      // function to make the hash function non-deterministic     size_t operator()(uint64_t x) const     {         static const uint64_t RANDOM             = chrono::steady_clock::now()                   .time_since_epoch()                   .count();         return splitmix64(x + RANDOM);     } };  int main() {     // Passing the custom hash function for the     // unordered map     unordered_map<long long, int, gfg_custom_hash> mp;     mp[1] = 10;     mp[2] = 20;     for (auto ele : mp) {         cout << ele.first << " " << ele.second << "\n";     }      // Passing the custom hash function for the     // unordered set     unordered_set<long long, gfg_custom_hash> st;     st.insert(1);     st.insert(2);     for (auto ele : st)         cout << ele << " ";     cout << "\n";      return 0; } 
Java
import java.util.*; import java.util.concurrent.TimeUnit;  class GFGCustomHash {     static class GFGCustomHashFunction {         static long splitmix64(long key) {             key += 0x9e3779b97f4a7c15L;             key = (key ^ (key >> 30)) * 0xbf58476d1ce4e5b9L;             key = (key ^ (key >> 27)) * 0x94d049bb133111ebL;             return key ^ (key >> 31);         }          // Function to make the hash function non-deterministic         public long apply(long x) {             final long RANDOM = System.nanoTime();             return splitmix64(x + RANDOM);         }     }      public static void main(String[] args) {         // Passing the custom hash function for the unordered map         HashMap<Long, Integer> map = new HashMap<>(16, 0.75f);         GFGCustomHashFunction customHashFunction = new GFGCustomHashFunction();         for (long i = 1; i <= 2; i++) {             map.put(i, (int) (i * 10));         }          for (Map.Entry<Long, Integer> entry : map.entrySet()) {             System.out.println(entry.getKey() + " " + entry.getValue());         }          // Passing the custom hash function for the unordered set         HashSet<Long> set = new HashSet<>(16, 0.75f);         for (long i = 1; i <= 2; i++) {             set.add(i);         }          for (Long element : set) {             System.out.print(element + " ");         }         System.out.println();     } } 
C#
using System; using System.Collections.Generic;  public class GFGCustomHash {     // Define a struct to implement custom hash function     public struct GFGCustomHashFunction : IEqualityComparer<long>     {         public bool Equals(long x, long y)         {             return x == y;         }          public int GetHashCode(long obj)         {             // Call the static Apply method to generate the hash code             return (int)Apply((ulong)obj);         }          public static ulong SplitMix64(ulong key)         {             key += 0x9e3779b97f4a7c15UL;             key = (key ^ (key >> 30)) * 0xbf58476d1ce4e5b9UL;             key = (key ^ (key >> 27)) * 0x94d049bb133111ebUL;             return key ^ (key >> 31);         }          // Function to make the hash function non-deterministic         public static ulong Apply(ulong x)         {             // Use a different approach for generating random value in C#,             // as there's no direct equivalent to chrono::steady_clock::now().time_since_epoch().count() in C#.             ulong RANDOM = (ulong)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();             return SplitMix64(x + RANDOM);         }     }      public static void Main(string[] args)     {         // Passing the custom hash function for the unordered map         Dictionary<long, int> map = new Dictionary<long, int>(new GFGCustomHashFunction());         map.Add(1, 10);         map.Add(2, 20);         foreach (var pair in map)         {             Console.WriteLine(pair.Key + " " + pair.Value);         }          // Passing the custom hash function for the unordered set         HashSet<long> set = new HashSet<long>(new GFGCustomHashFunction());         set.Add(1);         set.Add(2);         foreach (var element in set)         {             Console.Write(element + " ");         }         Console.WriteLine();     } } 
JavaScript
class GFGCustomHashFunction {     static splitmix64(key) {         key += 0x9e3779b97f4a7c15n;         key = (key ^ (key >> 30n)) * 0xbf58476d1ce4e5b9n;         key = (key ^ (key >> 27n)) * 0x94d049bb133111ebn;         return key ^ (key >> 31n);     }      // Function to make the hash function non-deterministic     static apply(x) {         const RANDOM = process.hrtime.bigint();         return GFGCustomHashFunction.splitmix64(x + RANDOM);     } }  class GFGCustomHash {     static main() {         // Passing the custom hash function for the unordered map         const map = new Map();         for (let i = 1n; i <= 2n; i++) {             map.set(i, Number(i * 10n));         }          for (const [key, value] of map) {             console.log(key + " " + value);         }          // Passing the custom hash function for the unordered set         const set = new Set();         for (let i = 1n; i <= 2n; i++) {             set.add(i);         }          for (const element of set) {             process.stdout.write(element + " ");         }         console.log();     } }  GFGCustomHash.main(); 
Python3
# Python Implementation import random  class CustomHash:     @staticmethod     def splitmix64(key):         key += 0x9e3779b97f4a7c15         key = (key ^ (key >> 30)) * 0xbf58476d1ce4e5b9         key = (key ^ (key >> 27)) * 0x94d049bb133111eb         return key ^ (key >> 31)      @staticmethod     def random_hash(x):         RANDOM = random.randint(0, 2**64 - 1)         return CustomHash.splitmix64(x + RANDOM)      def __hash__(self, x):         return self.random_hash(x)  if __name__ == "__main__":     # Using Python dictionary     mp = {}     mp[1] = 10     mp[2] = 20     for key, value in mp.items():         print(key, value)      # Using Python set     st = set()     st.add(1)     st.add(2)     for ele in st:         print(ele)  # This code is contributed by Tapesh(tapeshdua420) 

Output
2 20 1 10 2 1  

Hashing in Competitive Programming for Java Programmers:

Java has HashMaps with a hashing function which is applied to the key to calculate the index of the bucket in order to store and retrieve any key-value pair. The Capacity of HashMap is the number of buckets in it. Initially, the capacity of HashMap is 16. As the number of elements in the HashMap increases, the capacity gets increased. This is handled with the help of Load Factor. The load factor is the measure that decides when to increase the capacity of the Map. The default load factor is 75% of the capacity.

HashMap stores and retrieves entries in constant time O(1). However, the problem arises when the number of items is increased, and the number of buckets is fixed, which can increase the time complexity from O(1) to O(N). This can be solved by increasing the number of buckets and redistributing the items across all the buckets. In this way, we’ll be able to keep a constant number of items in each bucket and maintain the time complexity of O(1). With a lower load factor, there will be more free buckets and, hence, fewer chances of a collision. This will help us to achieve better performance for our Map. Hence, we need to keep the load factor low to achieve low time complexity.

Note: A higher value of load factor decreases the space overhead but increases the lookup cost.

Prior to Java 8, HashMap in Java used a LinkedList to store map entries when collisions occurred. This could lead to worst-case performance of O(n), which is not ideal. Java 8 and later versions addressed this issue by using a balanced tree, also known as a red-black tree, to store collided entries. This improves the worst-case performance of HashMap to O(log n), which is a significant improvement.

The TREEIFY_THRESHOLD constant determines when HashMap switches from using a LinkedList to a balanced tree. The current value of this constant is 8, meaning that if there are more than 8 elements in the same bucket, HashMap will use a tree to store them. This ensures that the LinkedList is not used for excessively large buckets, preventing performance degradation.

Java also offers a data structure as TreeMap which is used to store unique elements in a sorted order. Java.util.TreeMap uses a red-black tree in the background which makes sure that there are no duplicates. Additionally, it also maintains the elements in a sorted order. It takes the time complexity of log(N) to insert, delete or retrieve elements from TreeMap.

How to handle collision attacks?

Java handles collisions in its HashMap implementation without requiring users to create custom hash functions. The HashMap class in Java uses a combination of techniques to handle collisions and ensure efficient key-value storage. The key approach is employing separate chaining, which means that each bucket in the hash table is implemented as a linked list. When a collision occurs (i.e., multiple keys hash to the same bucket), the corresponding entries are stored in the linked list associated with that bucket.

Below is an example of Hashing in Competitive Programming for Java:

C++
#include <iostream> #include <unordered_map>  int main() {     // Create a new unordered_map object     std::unordered_map<std::string, int> myMap;      // Add some key-value pairs to the unordered_map     myMap["apple"] = 1;     myMap["banana"] = 2;     myMap["cherry"] = 3;      // Print the unordered_map     std::cout << "Original unordered_map: ";     for (const auto& pair : myMap) {         std::cout << "{" << pair.first << ": " << pair.second << "} ";     }     std::cout << std::endl;      // Get the value associated with the key "banana"     int value = myMap["banana"];      // Print the value     std::cout << "Value of key 'banana': " << value << std::endl;      // Remove the key-value pair associated with the key "cherry"     myMap.erase("cherry");      // Print the unordered_map again     std::cout << "Updated unordered_map: ";     for (const auto& pair : myMap) {         std::cout << "{" << pair.first << ": " << pair.second << "} ";     }     std::cout << std::endl;      return 0; } // code is contributed by utkarsh 
Java
import java.util.HashMap;  public class Main {     public static void main(String[] args) {         // Create a new HashMap object         HashMap<String, Integer> myMap = new HashMap<String, Integer>();          // Add some key-value pairs to the HashMap         myMap.put("apple", 1);         myMap.put("banana", 2);         myMap.put("cherry", 3);          // Print the HashMap         System.out.println("Original HashMap: " + myMap);          // Get the value associated with the key "banana"         int value = myMap.get("banana");          // Print the value         System.out.println("Value of key 'banana': " + value);          // Remove the key-value pair associated with the key "cherry"         myMap.remove("cherry");          // Print the HashMap again         System.out.println("Updated HashMap: " + myMap);     } } 
C#
using System; using System.Collections.Generic;  class Program {     static void Main(string[] args)     {         // Create a new Dictionary object         Dictionary<string, int> myMap = new Dictionary<string, int>();          // Add some key-value pairs to the Dictionary         myMap["apple"] = 1;         myMap["banana"] = 2;         myMap["cherry"] = 3;          // Print the Dictionary         Console.Write("Original Dictionary: ");         foreach (var pair in myMap)         {             Console.Write("{" + pair.Key + ": " + pair.Value + "} ");         }         Console.WriteLine();          // Get the value associated with the key "banana"         int value = myMap["banana"];          // Print the value         Console.WriteLine("Value of key 'banana': " + value);          // Remove the key-value pair associated with the key "cherry"         myMap.Remove("cherry");          // Print the Dictionary again         Console.Write("Updated Dictionary: ");         foreach (var pair in myMap)         {             Console.Write("{" + pair.Key + ": " + pair.Value + "} ");         }         Console.WriteLine();     } } 
JavaScript
// Create a new Map object let myMap = new Map();  // Add some key-value pairs to the Map myMap.set("apple", 1); myMap.set("banana", 2); myMap.set("cherry", 3);  // Print the Map console.log("Original Map:"); for (let [key, value] of myMap) {     console.log(`{${key}: ${value}}`); }  // Get the value associated with the key "banana" let value = myMap.get("banana");  // Print the value console.log("Value of key 'banana':", value);  // Remove the key-value pair associated with the key "cherry" myMap.delete("cherry");  // Print the Map again console.log("Updated Map:"); for (let [key, value] of myMap) {     console.log(`{${key}: ${value}}`); } 
Python3
# Create a new dictionary my_dict = {}  # Add some key-value pairs to the dictionary my_dict["apple"] = 1 my_dict["banana"] = 2 my_dict["cherry"] = 3  # Print the dictionary print("Original dictionary:", my_dict)  # Get the value associated with the key "banana" value = my_dict["banana"]  # Print the value print("Value of key 'banana':", value)  # Remove the key-value pair associated with the key "cherry" my_dict.pop("cherry", None)  # Print the dictionary again print("Updated dictionary:", my_dict) #this code is contributed by Kishan  

Output
Original unordered_map: {cherry: 3} {banana: 2} {apple: 1}  Value of key 'banana': 2 Updated unordered_map: {banana: 2} {apple: 1}  


Hashing in Competitive Programming for Python Programmers:

Python offers dictionaries to store (key, value) pairs. A hash table is a data structure that stores a set of elements in an array of large size, defining the position of the element as its hash taken modulo the size of the array. If hashes of several elements give the same cell in the hash table, the hash table tries to take another cell according to some rule, which depends on the particular implementation of the table. Usually, if the hash f(x) leads to a collision, then it checks the next hash f(f(x)), then f(f(f(x))) and so on, until an empty cell is found. The function f(x) is often a linear transformation (a*x+b)%size, where size is the size of the array, and a and b are relatively prime with it.

Python uses a hash table with an array size equal to a power of two to implement dict, and the transformation is slightly more complex than a simple linear one f(x) = (5x+1+perturb) % size, where perturb is initially equal to hash, but is shifted right by 5 bits in each step. Also in Python, up to very large numbers (around 10^18), hash of a number is the number itself, which is easily predictable.

How to handle collision attacks?

We can prevent the collision attacks by creating a custom type (Wrapper) with a unique hash function that incorporates a random number, the code introduces an additional layer of unpredictability into the hash values. This makes it more challenging for attackers to manipulate or predict the hash values and helps prevent collision attacks in scenarios where the default hash function might be vulnerable.

Below is an example of a custom hash function which one can use to avoid collision attacks.

C++
#include <iostream> #include <unordered_map> #include <ctime> #include <cstdlib>  // Custom hash to avoid collisions struct Wrapper {     int x;     Wrapper(int x) : x(x) {}     bool operator==(const Wrapper &other) const { return x == other.x; } };  // Custom hash function struct WrapperHash {     int RANDOM = rand() % 1000000000 + 1; // Random number from 1 to 10^9     std::size_t operator()(const Wrapper& k) const {         return std::hash<int>()(k.x) ^ RANDOM;     } };  int main() {     srand(time(0)); // Seed for random number generation      std::unordered_map<Wrapper, int, WrapperHash> freqDict;     int a[] = {1, 1, 2, 3, 1, 4, 5, 6, 7};      for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++) {         // Using Custom hash values         Wrapper wx(a[i]);         freqDict[wx]++;     }      // Print frequency dictionary in the desired format     std::cout << "{";     for (auto it = freqDict.begin(); it != freqDict.end(); ++it) {         std::cout << it->first.x << ": " << it->second;         if (std::next(it) != freqDict.end()) {             std::cout << ", ";         }     }     std::cout << "}" << std::endl;      return 0; } 
Java
import java.util.*;  public class Main {     static class Wrapper {         int value;          public Wrapper(int value) {             this.value = value;         }          @Override         public boolean equals(Object o) {             if (this == o) return true;             if (o == null || getClass() != o.getClass()) return false;             Wrapper wrapper = (Wrapper) o;             return value == wrapper.value;         }          @Override         public int hashCode() {             return Objects.hash(value);         }          @Override         public String toString() {             return "{" + value + "}";         }     }      public static void main(String[] args) {         int[] a = {1, 1, 2, 3, 1, 4, 5, 6, 7};         Map<Integer, Integer> freqDict = new LinkedHashMap<>();          for (int x : a) {             freqDict.put(x, freqDict.getOrDefault(x, 0) + 1);         }          System.out.print("{");         boolean first = true;         for (Map.Entry<Integer, Integer> entry : freqDict.entrySet()) {             if (!first) {                 System.out.print(", ");             } else {                 first = false;             }             System.out.print(entry.getKey() + ": " + entry.getValue());         }         System.out.println("}");     } } 
JavaScript
// Custom hash to avoid collisions class Wrapper {     constructor(x) {         this.x = x;     }      equals(other) {         return this.x === other.x;     }      // Custom string representation     toString() {         return String(this.x); // Convert the value of x to a string     } }  // Initialize frequency dictionary let freqDict = new Map();  let a = [1, 1, 2, 3, 1, 4, 5, 6, 7];  for (let i = 0; i < a.length; i++) {     // Using Custom hash values     let wx = new Wrapper(a[i]);     let key = wx.toString(); // Convert the Wrapper object to a string for use as a key     let count = freqDict.get(key) || 0;     freqDict.set(key, count + 1); }  // Print frequency dictionary let output = "{ "; for (let [key, value] of freqDict) {     output += key + ": " + value + ", "; } output = output.slice(0, -2); // Remove the trailing comma and space output += " }"; console.log(output); 
Python3
from random import randint  # Random number from 1 to 10^9 RANDOM = randint(1, 10 ** 9)  # Custom hash to avoid collisions  class Wrapper(int):     def __init__(self, x):         int.__init__(x)      def __hash__(self):         return super(Wrapper, self).__hash__() ^ RANDOM   a = [1, 1, 2, 3, 1, 4, 5, 6, 7] freqDict = dict() mx = 0 for x in a:         # Using Custom hash values     wx = Wrapper(x)     freqDict[wx] = freqDict.get(wx, 0) + 1 print(freqDict) 

Output
{7: 1, 6: 1, 5: 1, 1: 3, 4: 1, 2: 1, 3: 1} 

Practice Problems on Hashing for Competitive Programming:

Easy Level Problems on Hashing:

Problem

Problem Link

Count Pairs with given Sum

Practice Now

Subarray with 0 Sum

Practice Now

Key Pair

Practice Now

First Repeating Element

Practice Now

Non Repeating Character

Practice Now

Medium Level Problems on Hashing:

Problem

Problem Link

Find triplets with 0 sum

Practice Now

Longest Consecutive Subsequence

Practice Now

Largest Subarray with 0 Sum

Practice Now

Longest Subarray with Sum K

Practice Now

Top K Frequent Elements in the array

Practice Now

Hard Level Problems on Hashing:

Problem

Problem Link

Smallest Window in a string containing all the characters of another string

Practice Now

LRU Cache

Practice Now

Minimum operations to convert array A to B

Practice Now

Largest rectangular sub-matrix whose sum is 0

Practice Now

Account Merge

Practice Now



Next Article
Queue for Competitive Programming

M

mrityuanjay8vae
Improve
Article Tags :
  • Hash
  • Competitive Programming
  • DSA
  • Data Structures-Hash
Practice Tags :
  • Hash

Similar Reads

  • Learning the art of Competitive Programming
    Learning the art of Competitive Programming How to begin with Competitive Programming?Top 10 Algorithms and Data Structures for Competitive ProgrammingHow to prepare for ACM – ICPC?How to prepare for Google Asia Pacific University (APAC) Test ?Remaining Ahead in Competitive Programming:Master in com
    2 min read
  • Best Courses on Competitive Programming
    Competitive programming has gone beyond being a niche interest. Has become a skill, for computer science enthusiasts. Being able to solve algorithmic problems is highly valued in the tech industry. Recognizing this demand various online platforms offer courses tailored to skill levels and learning p
    5 min read
  • Queue for Competitive Programming
    In competitive programming, a queue is a data structure that is often used to solve problems that involve tasks that need to be completed in a specific order. This article explores the queue data structure and identifies its role as a critical tool for overcoming coding challenges in competitive pro
    8 min read
  • Stack for Competitive Programming
    For competitive programming to be successful, efficient data structures and algorithms are essential. The stack is one such tool. In this article, we will examine how stack data structures play an important role in solving problems efficiently during competitive programming challenges. We will explo
    7 min read
  • Arrays for Competitive Programming
    In this article, we will be discussing Arrays which is one of the most commonly used data structure. It also plays a major part in Competitive Programming. Moreover, we will see built-in methods used to write short codes for array operations that can save some crucial time during contests. Table of
    15+ min read
  • Competitive Programming: Conquering a given problem
    Programming is the process of developing and implementing sets of instructions to enable a computer to do a certain task.The programming contests like ACM ICPC, Google CodeJam, and IEEE Extreme etc. are delightful playgrounds for the exploration of intelligence of programmers. From knowing the conte
    5 min read
  • DP on Trees for Competitive Programming
    Dynamic Programming (DP) on trees is a powerful algorithmic technique commonly used in competitive programming. It involves solving various tree-related problems by efficiently calculating and storing intermediate results to optimize time complexity. By using the tree structure, DP on trees allows p
    15+ min read
  • Competitive Programming - A Complete Guide
    Competitive Programming is a mental sport that enables you to code a given problem under provided constraints. The purpose of this article is to guide every individual possessing a desire to excel in this sport. This article provides a detailed syllabus for Competitive Programming designed by indust
    8 min read
  • Competitive Programming vs General Programming
    Programming enthusiasts face a crossroads - Competitive Programming or General Programming? This article sheds light on the distinctions between Competitive Programming vs General Programming, offering a quick guide for those navigating the coding landscape. Whether you're aiming for speed and preci
    3 min read
  • String Guide for Competitive Programming
    Strings are a sequence of characters, and are one of the most fundamental data structures in Competitive Programming. String problems are very common in competitive programming contests, and can range from simple to very challenging. In this article we are going to discuss about most frequent string
    15 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences