Given a non-negative number n . The problem is to set the rightmost unset bit in the binary representation of n.
Examples:
Input: n = 6
Output: 7
Explanation: The binary representation of 6 is 110. After setting right most bit it becomes 111 which is 7.
Input: n = 15
Output: 31
Explanation: The binary representation of 15 is 01111. After setting right most bit it becomes 11111 which is 31.
Table of Content
[Naive Approach] Checking Bits One by One - O(log n) Time and O(1) Space
The Idea is to check each bit from right to left. Find the first bit which is 0 and set it to 1. If all bits are already set, return the number unchanged.
Algorithm:
- Check if n == 0; if yes, return 1.
- Start checking bits from the least significant bit (position 0).
- For each position i, check if the bit is unset using (n & (1 << i)) == 0.
- If an unset bit is found, set it using n |= (1 << i) and stop further checking.
#include <iostream>
using namespace std;
// Function to set the rightmost unset bit of n
int setBit(int n) {
// If n is 0, return 1 (set the first bit)
if (n == 0)
return 1;
// Traverse all bit positions from LSB to MSB
for (int i = 0; i < 31; i++) {
// Check if the i-th bit is unset
if ((n & (1 << i)) == 0) {
// Set the i-th bit
n |= (1 << i);
// Stop after setting the first (rightmost) unset bit
break;
}
}
return n;
}
int main() {
int n = 6;
cout << setBit(n);
return 0;
}
#include <stdio.h>
// Function to set the rightmost unset bit of n
int setBit(int n) {
// If n is 0, return 1 (set the first bit)
if (n == 0)
return 1;
// Traverse all bit positions from LSB to MSB
for (int i = 0; i < 31; i++) {
// Check if the i-th bit is unset
if ((n & (1 << i)) == 0) {
// Set the i-th bit
n |= (1 << i);
// Stop after setting the first (rightmost) unset bit
break;
}
}
return n;
}
int main() {
int n = 6;
printf("%d", setBit(n));
return 0;
}
public class GfG {
// Function to set the rightmost unset bit of n
public static int setBit(int n) {
// If n is 0, return 1 (set the first bit)
if (n == 0)
return 1;
// Traverse all bit positions from LSB to MSB
for (int i = 0; i < 31; i++) {
// Check if the i-th bit is unset
if ((n & (1 << i)) == 0) {
// Set the i-th bit
n |= (1 << i);
// Stop after setting the first (rightmost) unset bit
break;
}
}
return n;
}
public static void main(String[] args) {
int n = 6;
System.out.println(setBit(n));
}
}
def setBit(n):
# If n is 0, return 1 (set the first bit)
if n == 0:
return 1
# Traverse all bit positions from LSB to MSB
for i in range(31):
# Check if the i-th bit is unset
if (n & (1 << i)) == 0:
# Set the i-th bit
n |= (1 << i)
# Stop after setting the first (rightmost) unset bit
break
return n
if __name__ == '__main__':
n = 6
print(setBit(n))
using System;
public class GfG {
// Function to set the rightmost unset bit of n
public static int setBit(int n) {
// If n is 0, return 1 (set the first bit)
if (n == 0)
return 1;
// Traverse all bit positions from LSB to MSB
for (int i = 0; i < 31; i++) {
// Check if the i-th bit is unset
if ((n & (1 << i)) == 0) {
// Set the i-th bit
n |= (1 << i);
// Stop after setting the first (rightmost) unset bit
break;
}
}
return n;
}
public static void Main() {
int n = 6;
Console.WriteLine(setBit(n));
}
}
function setBit(n) {
// If n is 0, return 1 (set the first bit)
if (n === 0)
return 1;
// Traverse all bit positions from LSB to MSB
for (let i = 0; i < 31; i++) {
// Check if the i-th bit is unset
if ((n & (1 << i)) === 0) {
// Set the i-th bit
n |= (1 << i);
// Stop after setting the first (rightmost) unset bit
break;
}
}
return n;
}
// Example usage:
let n = 6;
console.log(setBit(n));
Output
7
[Better Approach] Using Complement - O(1) Time and O(1) Space
- The idea is to find the rightmost set bit using a property of 2's complement arithmetic. When we perform n & (~n + 1) or equivalently n & (-n), we get a number with only the rightmost set bit of n.
- Then we can use log2 to find its position. Let the position be pos.
- Finally we set the bit by doing OR of n and (1 << (pos - 1))
// C++ implementation to set the rightmost unset bit
#include <bits/stdc++.h>
using namespace std;
// function to find the position
// of rightmost set bit
int getPosOfRightmostSetBit(int n)
{
return log2(n & -n) + 1;
}
int setBit(int n)
{
// If n is 0, return 1
if (n == 0)
return 1;
// isolate rightmost unset bit, the num
// will have only one bit set
int num = (~n) & (n + 1);
// Find the position of the only set bit
int pos = getPosOfRightmostSetBit(num);
// Set this bit in n and return
int mask = (1 << (pos - 1));
return (n | mask);
};
// Driver program
int main()
{
int n = 15;
cout << setBit(n);
return 0;
}
#include <stdio.h>
#include <math.h>
// function to find the position
// of rightmost set bit
int getPosOfRightmostSetBit(int n)
{
return log2(n & -n) + 1;
}
int setBit(int n)
{
// If n is 0, return 1
if (n == 0)
return 1;
// isolate rightmost unset bit, the num
// will have only one bit set
int num = (~n) & (n + 1);
// Find the position of the only set bit
int pos = getPosOfRightmostSetBit(num);
// Set this bit in n and return
int mask = (1 << (pos - 1));
return (n | mask);
};
// Driver program
int main()
{
int n = 15;
printf("%d", setBit(n));
return 0;
}
import java.util.*;
import java.lang.Math;
public class Main {
// function to find the position
// of rightmost set bit
static int getPosOfRightmostSetBit(int n) {
return (int)(Math.log(n & -n) / Math.log(2)) + 1;
}
static int setBit(int n) {
// If n is 0, return 1
if (n == 0)
return 1;
// isolate rightmost unset bit, the num
// will have only one bit set
int num = (~n) & (n + 1);
// Find the position of the only set bit
int pos = getPosOfRightmostSetBit(num);
// Set this bit in n and return
int mask = (1 << (pos - 1));
return (n | mask);
}
public static void main(String[] args) {
int n = 15;
System.out.println(setBit(n));
}
}
import math
# function to find the position
# of rightmost set bit
def getPosOfRightmostSetBit(n):
return int(math.log2(n & -n)) + 1
def setBit(n):
# If n is 0, return 1
if n == 0:
return 1
# isolate rightmost unset bit, the num
# will have only one bit set
num = (~n) & (n + 1)
# Find the position of the only set bit
pos = getPosOfRightmostSetBit(num)
# Set this bit in n and return
mask = 1 << (pos - 1)
return n | mask
# Driver program
n = 15
print(setBit(n))
using System;
public class GfG {
// function to find the position
// of rightmost set bit
static int GetPosOfRightmostSetBit(int n) {
return (int)Math.Log(n & -n, 2) + 1;
}
static int SetBit(int n) {
// If n is 0, return 1
if (n == 0)
return 1;
// isolate rightmost unset bit, the num
// will have only one bit set
int num = (~n) & (n + 1);
// Find the position of the only set bit
int pos = GetPosOfRightmostSetBit(num);
// Set this bit in n and return
int mask = 1 << (pos - 1);
return n | mask;
}
public static void Main() {
int n = 15;
Console.WriteLine(SetBit(n));
}
}
// function to find the position
// of rightmost set bit
function getPosOfRightmostSetBit(n) {
return Math.log2(n & -n) + 1;
}
function setBit(n) {
// If n is 0, return 1
if (n === 0)
return 1;
// isolate rightmost unset bit, the num
// will have only one bit set
let num = (~n) & (n + 1);
// Find the position of the only set bit
let pos = getPosOfRightmostSetBit(num);
// Set this bit in n and return
let mask = 1 << (pos - 1);
return n | mask;
};
// Driver program
let n = 15;
console.log(setBit(n));
Output
31
[Expected Approach] Using n | (n + 1) Trick to Set Rightmost Unset Bit - O(1) Time and O(1) Space
The idea is based on the property that n | (n + 1) sets the rightmost unset bit of a number. However, this also affects numbers where all bits are already set (like 2^k - 1). So, we first check if all bits are set; if yes, we return the number as it is. Otherwise, we apply n | (n + 1) to set the required bit.
// C++ implementation to set the rightmost unset bit
#include <bits/stdc++.h>
using namespace std;
int setBit(int n)
{
// Special cases
if (n == 0)
return 1;
// Set the rightmost unset bit
return n | (n + 1);
}
// Driver program to test above
int main()
{
int n = 15;
cout << setBit(n);
return 0;
}
#include <stdio.h>
int setBit(int n)
{
// Special cases
if (n == 0)
return 1;
// Set the rightmost unset bit
return n | (n + 1);
}
int main()
{
int n = 15;
printf("%d", setBit(n));
return 0;
}
public class Main {
public static int setBit(int n) {
// Special cases
if (n == 0)
return 1;
// Set the rightmost unset bit
return n | (n + 1);
}
public static void main(String[] args) {
int n = 15;
System.out.println(setBit(n));
}
}
def setBit(n):
# Special cases
if n == 0:
return 1
# Set the rightmost unset bit
return n | (n + 1)
if __name__ == '__main__':
n = 15
print(setBit(n))
using System;
class GfG {
static int setBit(int n) {
// Special cases
if (n == 0)
return 1;
// Set the rightmost unset bit
return n | (n + 1);
}
static void Main() {
int n = 15;
Console.WriteLine(setBit(n));
}
}
function setBit(n) {
// Special cases
if (n === 0)
return 1;
// Set the rightmost unset bit
return n | (n + 1);
}
let n = 15;
console.log(setBit(n));
Output
31
Time complexity: O(1)
Space Complexity: O(1)