Counter II solution and explanation
9 more videos on this problem
Counter (Closure - Day3) - Leetcode 2665 - JavaScript 30-Day ChallengeNeetCodeIO · 7:26 · 28K views
2665. Counter II - Leetcode JavaScript Solution with Explanation | ClosureEndeavour Monk · 5:50 · 2K views
#day4 | 2665. Counter II | 30 Days of Javascript | Leetcode-2665 | 30 Days Challenge | ClosuresCoding with Ankita · 9:38 · 859 views
Counter II | 30 Days of JavaScript | LEETCODE 2665 | CLOSUREcode Explainer · 6:46 · 471 views
2665. Counter II - Day 3/30 Leetcode Javascript ChallengeProgramming Live with Larry · 2:41 · 287 views
2665. Counter II 😎 closure🔥 || JavaScript 30 Days Challenge #leetcode #javascript #closurePhoenix Code Lover · 5:23 · 166 views
Leetcode Day 3 JavaScript Challenge Solution: 2665. Counter IIvanAmsen · 4:02 · 123 views
Counter II (Leetcode 2665) in TeluguCoding Interview Preparation · 2:39 · 107 views
Counter II - Leetcode 2665 - PythonAlgorithms Casts · 6:56 · 79 views
2665. Counter IIDSA_REALM · 2:43 · 75 views
The problem
Write a function createCounter. It should accept an initial integer init. It should return an object with three functions.
The three functions are:
increment()increases the current value by 1 and then returns it.decrement()reduces the current value by 1 and then returns it.reset()sets the current value toinitand then returns it.
Example 1:
Input: init = 5, calls = ["increment","reset","decrement"] Output: [6,5,4] Explanation: const counter = createCounter(5); counter.increment(); // 6 counter.reset(); // 5 counter.decrement(); // 4
Example 2:
Input: init = 0, calls = ["increment","increment","decrement","reset","reset"] Output: [1,2,1,0,0] Explanation: const counter = createCounter(0); counter.increment(); // 1 counter.increment(); // 2 counter.decrement(); // 1 counter.reset(); // 0 counter.reset(); // 0
Constraints:
-1000 <= init <= 10000 <= calls.length <= 1000calls[i]is one of "increment", "decrement" and "reset"
Approach overview
Problem Overview: You need to design a counter that starts from an initial value and supports three operations: increment(), decrement(), and reset(). Each method updates or restores the internal state and returns the current counter value.
Approach 1: Closure-Based Counter (O(1) time, O(1) space)
This approach relies on closures to store the counter state inside a function scope. The outer function initializes the counter value, while the returned object exposes methods that operate on that captured variable. Each call to increment() increases the stored value, decrement() reduces it, and reset() restores it to the original initialization value. Because the variable lives in the closure, it persists across calls without using global state.
The key insight is that closures allow functions to retain access to variables from their creation scope. That makes them perfect for lightweight stateful utilities like counters. Each operation performs a constant‑time arithmetic update, so every method runs in O(1) time with O(1) additional space. This approach is common in JavaScript and Python implementations and is frequently discussed when learning closures and functional design patterns.
Approach 2: Class-Based Counter Object (O(1) time, O(1) space)
An alternative design uses an explicit class with instance variables to store the counter state. The constructor receives the initial value and stores both the current counter and the original value for resets. Methods like increment(), decrement(), and reset() modify the instance variable and return the updated value.
This approach follows classic object-oriented programming principles. State lives in class fields instead of closures, and behavior is defined through instance methods. The logic remains straightforward: update the stored integer and return the result. Each operation still runs in constant time O(1) with O(1) space overhead.
Class-based design is often preferred in strongly typed languages like Java or C#, where objects and method definitions are the natural way to encapsulate state. It also scales better if the counter later gains additional behaviors or configuration.
Recommended for interviews: The closure-based implementation is usually the expected solution in JavaScript because it demonstrates understanding of function scope and persistent state. The class-based approach is equally valid and shows good design thinking in languages centered around objects. Showing both approaches demonstrates strong grasp of state management and abstraction.
Approach 1: Closure-Based Counter
This approach uses closure to maintain the state of the counter. We create an outer function that returns three inner functions: increment, decrement, and reset. These functions have access to the outer function's scope where the initial state and current state are maintained.
def createCounter(init):
class Counter:
def __init__(self, init):
self.current = init
self.initial = init
def increment(self):
self.current += 1
return self.current
def decrement(self):
self.current -= 1
return self.current
def reset(self):
self.current = self.initial
return self.current
return Counter(init)function createCounter(init) {
let current = init;
return {
increment: function() {
return ++current;
},
decrement: function() {
return --current;
},
reset: function() {
current = init;
return current;
}
};
}In this Python solution, we define a class Counter inside the createCounter function. The class maintains the state of the counter which includes the current value and the initial value. It provides methods to increment, decrement, and reset the counter.
Time Complexity: O(1) for each operation.
Space Complexity: O(1).
Approach 2: Class-Based Counter Object
This approach involves creating a class outside the function that models the counter with methods for incrementing, decrementing, and resetting. An instance of this class is created and returned by the createCounter function.
class Counter {
private int current;
private final int initial;
public Counter(int init) {
this.current = init;
this.initial = init;
}
public int increment() {
return ++current;
}
public int decrement() {
return --current;
}
public int reset() {
current = initial;
return current;
}
}
public class CounterFactory {
public static Counter createCounter(int init) {
return new Counter(init);
}
}public class Counter {
private int current;
private readonly int initial;
public Counter(int init) {
current = init;
initial = init;
}
public int Increment() {
return ++current;
}
public int Decrement() {
return --current;
}
public int Reset() {
current = initial;
return current;
}
}
public class CounterFactory {
public static Counter CreateCounter(int init) {
return new Counter(init);
}
}A Java class named Counter is defined with private fields to hold the current and initial values. Its methods implement the required functionalities. The CounterFactory class provides a static method to create a counter instance.
Time Complexity: O(1) per operation.
Space Complexity: O(1) as the counter uses a fixed amount of memory.
Approach 3: Default Approach
type ReturnObj = {
increment: () => number;
decrement: () => number;
reset: () => number;
};
function createCounter(init: number): ReturnObj {
let val = init;
return {
increment() {
return ++val;
},
decrement() {
return --val;
},
reset() {
return (val = init);
},
};
}
/**
* const counter = createCounter(5)
* counter.increment(); // 6
* counter.reset(); // 5
* counter.decrement(); // 4
*/Complexity comparison
| Approach | Complexity |
|---|---|
| Closure-Based Counter | Time Complexity: O(1) for each operation. |
| Class-Based Counter Object | Time Complexity: O(1) per operation. |
| Default Approach | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Closure-Based Counter | O(1) per operation | O(1) | Best for JavaScript or Python when demonstrating closures and functional state management |
| Class-Based Counter Object | O(1) per operation | O(1) | Preferred in Java or C# where object-oriented structure is standard |
Frequently asked questions
Is Counter II easy or hard?
Counter II is categorized as an Easy problem. The challenge focuses on designing a small API and correctly maintaining internal state rather than complex algorithms or data structures.
Counter II Python/Java solution
Python solutions typically use closures where an outer function stores the counter and inner functions update it. Java implementations usually define a class with fields for the current and initial values, with methods for increment, decrement, and reset. Both approaches run in O(1) time per operation.
How to solve Counter II in O(1)?
Store the current counter value and the initial value as state. Each method directly modifies or restores the stored integer. Because the operations are simple arithmetic updates with no iteration, increment, decrement, and reset all run in O(1) time and O(1) space.
What is the best approach for Counter II?
The best approach is maintaining the counter state in either a closure or a class field. Both designs allow increment, decrement, and reset operations to update a stored variable in constant time. In JavaScript interviews, the closure-based solution is typically expected because it demonstrates understanding of persistent function scope.
Is Counter II asked at Google/Amazon/Meta?
Counter II represents a typical state‑management design problem used in technical interviews. Similar questions appear at companies like Amazon, Meta, and Google to evaluate understanding of closures, object state, and basic API design rather than algorithmic complexity.
What data structure is used in Counter II?
The solution primarily uses a single integer variable to store the counter value. The state is maintained either through a closure variable in JavaScript/Python or an instance field in a class for Java and C#. No additional data structures are required.
What is the time complexity of Counter II?
Each counter operation runs in O(1) time. Increment and decrement simply add or subtract one from the stored value, and reset restores the original initialization value. No loops or additional data structures are involved, so every call executes in constant time.
