3094. Guess the Number Using Bitwise Questions II 🔒
Problem Description
You are tasked with finding a number n
that initially ranges between 0
and 2^30 - 1
. This number n
can be dynamically altered with every interaction using a pre-defined API function, commonBits(int num)
. The goal is to determine the initial value of n
.
The commonBits(int num)
function works in the following manner:
- It calculates the number of bit positions where both
n
andnum
share the same value. - Then it updates
n
by applying an XOR operation betweenn
andnum
. - Finally, it returns the count of common bits.
Each time you invoke this function, the API produces an effect on n
, adding to the challenge of determining its initial value.
The constraints are as follows:
- Both
n
andnum
are within the range of0
to2^30 - 1
. - Requests for
num
out of the specified range will result in unreliable outputs.
Intuition
The solution is built on understanding how bit manipulation works in conjunction with the commonBits
function. The key observations are:
-
If
commonBits
is called twice with the same number, the net effect onn
is neutral; its value remains unchanged after the second call. -
For a given bit position
i
, when we callcommonBits(1 << i)
, we toggle thei
-th bit ofn
. If this bit inn
was originally1
, it becomes0
after the call, and vice versa.
By using this behavior, the solution can efficiently determine the initial value for each bit:
- For each bit
i
, use1 << i
to interact with thecommonBits
function. - Call
commonBits(1 << i)
twice to ascertain the state of thei
-th bit. - Compare the results: if the first call results in
count1
being greater than the second callcount2
, it indicates thei
-th bit of the initialn
was1
; otherwise, it was0
.
This approach efficiently reconstructs the original number n
by analyzing each bit position using simple bitwise operations.
Solution Approach
The solution approach utilizes bit manipulation and is based on the properties of the commonBits
function. The algorithm effectively reconstructs the initial number n
through a series of bitwise operations. Here’s a detailed walkthrough of the implementation:
-
Initialize a Variable for
n
:- Start with
n = 0
, which will be used to accumulate the bits of the original number.
- Start with
-
Loop Through Each Bit Position:
- A loop iterates through bit positions from
0
to31
. Even though the range only requires up to2^30 - 1
, checking all bits ensures we handle potential edge cases at the boundaries.
- A loop iterates through bit positions from
-
Call
commonBits
Twice Per Bit Position:- For each bit position
i
, use1 << i
to create a mask that isolates that specific bit. - Call
commonBits(1 << i)
twice:count1 = commonBits(1 << i)
: This call toggles thei
-th bit ofn
and returns the count of matching bits before toggling.count2 = commonBits(1 << i)
: The second call toggles thei
-th bit back to its original state and returns the new count of matching bits.
- For each bit position
-
Determine the Bit Value for the Original
n
:- Compare
count1
withcount2
:- If
count1 > count2
, it implies thei
-th bit in the originaln
was1
. - Else, the
i
-th bit was0
.
- If
- Compare
-
Update the Value of
n
:- If the
i
-th bit is determined to be1
, use bitwise OR to set thei
-th bit inn
:n |= 1 << i
- If the
-
Return the Reconstructed
n
:- After the loop completes,
n
will have been reconstructed to match its initial value before any calls tocommonBits
.
- After the loop completes,
This bit manipulation strategy efficiently determines each bit in constant time per bit, resulting in an overall time complexity of (O(1)), as the number of bits is fixed.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
To illustrate the solution approach, consider a scenario where the initial number n
is 6
, which in binary is 110
. We want to reconstruct n
using the commonBits
function.
-
Initialization:
- Start with
n = 0
. This will gradually be transformed into the initial value ofn
through bit manipulation.
- Start with
-
Iterate Through Bit Positions (0 to 31):
- We'll focus on bit positions relevant to
6
, which are0
,1
, and2
.
- We'll focus on bit positions relevant to
-
Processing Each Bit:
-
Bit Position 0:
- Call
commonBits(1 << 0)
twice. - Before the first call,
n = 110
andnum = 001
. Result:count1 = 1
(bit 0 matches). - After XOR operation,
n = 111
. - Second call with
1 << 0
:n = 111
andnum = 001
. Result:count2 = 2
(bits 1 and 2 match).
- Since
count1 < count2
, the original0
-th bit is0
.
- Call
-
Bit Position 1:
- Call
commonBits(1 << 1)
twice. - Before the first call,
n = 110
andnum = 010
. Result:count1 = 2
(bits 1 and 2 match). - After XOR operation,
n = 100
. - Second call with
1 << 1
:n = 100
andnum = 010
. Result:count2 = 1
(bit 2 matches).
- Since
count1 > count2
, the original1
-st bit is1
. - Update
n
asn |= 1 << 1
→n = 010
in binary, which is2
in decimal.
- Call
-
Bit Position 2:
- Call
commonBits(1 << 2)
twice. - Before the first call,
n = 110
andnum = 100
. Result:count1 = 2
(bits 1 and 2 match). - After XOR operation,
n = 010
. - Second call with
1 << 2
:n = 010
andnum = 100
. Result:count2 = 1
(bit 1 matches).
- Since
count1 > count2
, the original2
-nd bit is1
. - Update
n
asn |= 1 << 2
→n = 110
in binary, which is6
in decimal.
- Call
-
-
Final Result:
- After processing each relevant bit, the reconstructed
n
is6
, which matches the initial value.
- After processing each relevant bit, the reconstructed
This walkthrough demonstrates how to use the commonBits
function and bit manipulation to efficiently reconstruct the original number.
Solution Implementation
1# Definition of commonBits API.
2# def commonBits(num: int) -> int:
3
4
5class Solution:
6 def findNumber(self) -> int:
7 # Initialize the variable `n` which will hold the result number.
8 n = 0
9
10 # Loop through each bit position from 0 to 31.
11 for i in range(32):
12 # Query the number of integers with common bits set at the i-th position.
13 count1 = commonBits(1 << i)
14 # The second query for the sake of demonstration, but it seems redundant.
15 # If this is intended for comparison, it could make sense to modify any conditions.
16 count2 = commonBits(1 << i)
17
18 # Check if the count of numbers with the i-th bit set is greater than count2.
19 # Depending on the context of `commonBits`, this condition can vary.
20 if count1 > count2:
21 # Set the i-th bit of `n` to 1, effectively adjusting `n`.
22 n |= 1 << i
23
24 # Return the computed number.
25 return n
26
1/**
2 * Definition of commonBits API (defined in the parent class Problem).
3 * int commonBits(int num);
4 */
5
6public class Solution extends Problem {
7 public int findNumber() {
8 int n = 0; // This will hold the number we are trying to find
9
10 // Iterate over each bit position from 0 to 31 (since integers are usually 32 bits)
11 for (int i = 0; i < 32; ++i) {
12 // Check the number of common bits for current bit position
13 int count1 = commonBits(1 << i);
14 int count2 = commonBits(1 << i);
15
16 // If count1 is greater than count2, it indicates the bit at position 'i' might be set
17 // in the number we are looking for
18 if (count1 > count2) {
19 n |= 1 << i; // Set the 'i-th' bit in 'n'
20 }
21 }
22
23 return n; // Return the constructed number
24 }
25}
26
1/**
2 * Definition of the commonBits API, which is already provided.
3 * int commonBits(int num);
4 */
5
6class Solution {
7public:
8 int findNumber() {
9 int n = 0; // Initialize the result number to 0
10 for (int i = 0; i < 32; ++i) {
11 // Query the number of 1s when the i-th bit is set to 1.
12 int count1 = commonBits(1 << i);
13 // Query again to get the number of 1s when the i-th bit is set to 1.
14 // Note: Seems redundant, typically you'd compare `commonBits(n)` vs `commonBits(n | (1 << i))`
15 int count2 = commonBits(1 << i);
16
17 // If the count from the first query is greater, set the i-th bit of n
18 if (count1 > count2) {
19 n |= 1 << i; // Use bitwise OR to set the i-th bit
20 }
21 }
22 return n; // Return the constructed number
23 }
24};
25
1/**
2 * Definition of the commonBits function, which is already provided.
3 * function commonBits(num: number): number;
4 */
5
6// Global function to find the number using the commonBits API.
7function findNumber(): number {
8 let n = 0; // Initialize the result number to 0.
9
10 // Iterate over each bit position from 0 to 31 (assuming a 32-bit integer).
11 for (let i = 0; i < 32; ++i) {
12 // Calculate the value with only the i-th bit set to 1.
13 const bitMask = 1 << i;
14
15 // Query the number of 1s when the i-th bit is set to 1.
16 const count1 = commonBits(bitMask);
17
18 // Query again to confirm the result, checking the same bit mask.
19 const count2 = commonBits(bitMask);
20
21 // If the count from the first query is greater, set the i-th bit of n.
22 // However, in typical scenarios, you'd compare to `commonBits(n | bitMask)`.
23 if (count1 > count2) {
24 n |= bitMask; // Use bitwise OR to set the i-th bit.
25 }
26 }
27
28 return n; // Return the constructed number.
29}
30
Time and Space Complexity
The time complexity of the provided code is O(32)
, which simplifies to O(1)
as the loop runs a constant number of times (32 iterations). Each iteration involves calling the commonBits
function twice, which is assumed to run in constant time.
The space complexity is O(1)
because the amount of extra space used by the algorithm does not depend on the size of the input. The operations and variables like n
and constants used within the loop occupy a fixed amount of space.
Learn more about how to find time and space complexity quickly.
In a binary min heap, the maximum element can be found in:
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!