Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Use a hash map to record numbers already seen and their indices. For each array element, look for its complement before recording it. That single expected O(n)-time approach solves LeetCode 1 in C++, Java, and Elixir; the languages differ mainly in how they express and update state.

What LeetCode 1 asks you to return

Given an array and a target, return the indices of two distinct elements whose values add to the target. The prompt guarantees exactly one solution and accepts the indices in either order. It includes repeated values at different positions, such as [3,3] with target 6. The array length is 2 to 104; each value and the target are between −109 and 109. These are Two Sum I rules—not Two Sum II, which specifies sorted input, one-based indices, and constant extra space. LeetCode’s Two Sum statement asks whether you can find an algorithm faster than O(n²).

How the hash map finds the complement

At index i, let the current value be x. The value needed to reach the target is target - x. Keep a map from previously encountered values to their indices:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Check whether target - x is already in the map. If it is, return that stored index and i.
  2. If it is not, store x with index i and continue.

The map contains only earlier positions when the lookup happens. That ordering prevents an element from being paired with itself. It still handles duplicates correctly: the first 3 is stored, and the second 3 finds it when the target is 6.

#1 Best Overall
Sale
Cracking the Coding Interview: 189 Programming Questions and Solutions
  • Careercup, Easy To Read
  • Condition : Good
  • Compact for travelling

Store indices, not just values, because the required result is a pair of positions. Since the prompt promises one solution, a straightforward map that retains the first index for each value is sufficient.

C++: mutable local state with std::unordered_map

#include <unordered_map>
#include <vector>

class Solution {
public:
std::vector<int> twoSum(std::vector<int>& nums, int target) {
std::unordered_map<int, int> seen;

for (int i = 0; i < static_cast<int>(nums.size()); ++i) {
int complement = target - nums[i];
auto it = seen.find(complement);
if (it != seen.end()) {
return {it->second, i};
}
seen.emplace(nums[i], i);
}
return {};
}
};

The empty-vector return is only a fallback for a signature that must return a value; it is unreachable for valid inputs under the prompt’s exactly-one-solution guarantee. The lookup precedes emplace, preserving the earlier-indices invariant. The documented constraints fit in a signed int for both the input values and the complement calculation; avoid converting values to an unsigned type, which would change how negative numbers behave.

std::unordered_map is a hash table and does not keep its entries sorted. Its search and insertion are average constant time, so the scan is average O(n), rather than a guaranteed O(n) in every hash-table scenario. See cppreference’s std::unordered_map reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Java: the same loop with HashMap

import java.util.HashMap;
import java.util.Map;

class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> seen = new HashMap<>();

for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
Integer earlierIndex = seen.get(complement);
if (earlierIndex != null) {
return new int[] { earlierIndex, i };
}
seen.putIfAbsent(nums[i], i);
}
return new int[0];
}
}

get returns null when the complement is absent. Stored indices are non-null integers, so a non-null result indicates a match. putIfAbsent keeps the first index if a value occurs more than once. As in C++, the fallback empty array is not reached when the input satisfies the problem guarantee.

Java’s HashMap makes no ordering guarantee. Its API describes basic get and put operations as constant time when the hash function disperses elements properly; the overall scan is therefore described as expected or average O(n), not an unconditional worst-case guarantee. See Oracle’s Java SE 25 HashMap API.

Elixir: carry the map through a reducer

Elixir can express the same left-to-right traversal by carrying both the map and an optional answer in a reducer accumulator. Each iteration returns the next state. Once a pair is found, halt the reduction.

defmodule Solution do
def two_sum(nums, target) do
nums
|> Enum.with_index()
|> Enum.reduce_while({%{}, nil}, fn {x, i}, {seen, _answer} ->
complement = target - x

case Map.fetch(seen, complement) do
{:ok, earlier_index} ->
{:halt, {seen, [earlier_index, i]}}

:error ->
{:cont, {Map.put(seen, x, i), nil}}
end
end)
|> elem(1)
end
end

Enum.with_index/1 pairs each value with its zero-based index. Map.fetch/2 distinguishes a present key from an absent one, and the success branch returns the stored earlier index with the current index. On a miss, Map.put/3 produces the map for the next reducer step; if a match is found, Enum.reduce_while/3 halts immediately.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This is functional in how it makes state transitions explicit: the reducer receives a map and returns the next accumulator rather than mutating a local map. It is not a different algorithm. Elixir maps hold unique keys and are unordered; Map.put/3 adds a key or replaces its value. See the Elixir Map reference. The reference page is for Elixir 1.20.4; that should not be mistaken for the runtime listed for LeetCode.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What changes across the three versions—and what does not

Concern C++ Java Elixir
Map representation std::unordered_map<value, index> HashMap<value, index> Map from value to index
Lookup find, compare with end get, check for null Map.fetch/2, match {:ok, index} or :error
Record after a miss emplace putIfAbsent Map.put/3 returned in the next accumulator
State expression Mutable local map in a loop Mutable local map in a loop Explicit reducer accumulator
Stop after finding a pair return from the loop return from the loop {:halt, accumulator}

All three versions depend on the same invariant and return zero-based indices. The syntax changes how lookup, insertion, and early exit are expressed; it does not change the complement calculation or the reason for checking before insertion. No performance ranking among these language implementations follows from their syntax alone.

Complexity and common mistakes

  • Expected or average time: O(n), assuming hash lookups and insertions take constant time on average.
  • Additional space: O(n) in the number of distinct values stored; at most one entry is added for each scanned position.
  • Brute-force alternative: checking every pair takes O(n²) time and O(1) additional space. The hash-map method trades extra storage for a faster expected scan.
  • Inserting before checking: can let the current position match itself. Check the complement first.
  • Storing values without positions: cannot produce the required indices. Map each value to an index.
  • Assuming sorted input: Two Sum I does not promise sorted values. The two-pointer method associated with sorted input belongs to a different problem variant.
  • Claiming guaranteed O(n): hash-table operations have qualifications. Describe this scan as expected or average O(n).

LeetCode language versions

LeetCode’s Help Center article, updated March 2, 2026, lists C++ as clang 19 with C++23 and libstdc++ from GCC 14, Java as OpenJDK 25, and Elixir 1.17 with Erlang/OTP 26. These describe the platform’s listed environments and may change; the Elixir 1.20.4 reference cited above is not the same version as LeetCode’s listed Elixir runtime. See LeetCode’s language environment article.

Quick Recap

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.