Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Print numbers in the range 1 to n having bits in an alternate pattern
Alternate bit pattern implies the positioning of 0's and 1's in a number at an alternate position i.e. no two 0s or 1's are together. For example, 10 in binary representation is (1010)2 which has an alternate bit pattern as 0's and 1's are separated by each other.
Problem Statement
Given an integer, N. Find all the integers in the range 1 to N where the bit pattern of the integer is alternating.
Example 1
Input: 10
Output: 1, 2, 5, 10
Explanation
$\mathrm{(1)_{10} = (1)_2, (2)_{10} = (10)_2, (5)_{10} = (101)_2, (10)_{10} = (1010)_2}$
Example 2
Input: 31
Output: 1, 2, 5, 10, 21
Explanation
$\mathrm{(1)_{10} = (1)_2, (2)_{10} = (10)_2, (5)_{10} = (101)_2, (10)_{10} = (1010)_2, (21)_{10} = (10101)_2}$
Approach 1: Check for Alternate Pattern
The naive approach to solve this problem would be to check for every number in the range 1 to n if it has bits in an alternate pattern or not.
This can be done as follows,
For checking if a number has an alternate bit pattern, we can use the truth table of the AND operation to check if consecutive bits are different.
Pseudocode ?
procedure checkAltPattern (num)
temp = num
count = 0
while (temp)
count = count +1
num = num >> 1
end while
for i = 0 to count - 2
iTh = num >> i
i2Th = num >> (i + 2)
if ((iTh & 1) != (i2Th & 1))
ans = FALSE
end if
end for
ans = TRUE
end procedure
procedure numbers (num)
ans []
for i = 1 to num
if checkAltPattern = TRUE
ans.add(i)
end if
end for
end procedure
Example
In the following program, we check for every number in the range 1 to N if they have an alternate bit pattern by checking if, at every alternate position, the same bits are present or not.
#include <bits/stdc++.h>
using namespace std;
// Function to check if the number has alternate pattern
bool checkAltPattern(int num){
int temp = num, count = 0;
// Counting total bits of the number by using the right shift operator
while (temp) {
count++;
// Right shift of a number shift all the bits one position right
temp >>= 1;
}
// For every alternate position checking if bits are same
for (int i = 0; i < (count - 1); i++) {
int iTh = num >> i, i2Th = num >> (i + 2);
// iTh & 1 gives the bit at ith position
// i2Th &N1 gives the bit at (i+2)th position
// If both bits are not same then bits pattern is not alternate
if ((iTh & 1) != (i2Th & 1)) {
return false;
}
}
return true;
}
vector<int> numbers(int num){
// Initializing an array to add numbers with alternate bit pattern
vector<int> ans;
for (int i = 1; i <= num; i++){
if (checkAltPattern(i)){
ans.push_back(i);
}
}
return ans;
}
int main(){
int N = 50;
cout << "Numbers in range 1 to " << N << " having alternate bit pattern : ";
vector<int> res = numbers(N);
for (int i = 0; i < res.size(); i++){
cout << res[i] << " ";
}
return 0;
}
Output
Numbers in range 1 to 50 having alternate bit pattern : 1 2 5 10 21 42
Time Complexity ? O(nlogn) as the for each number we check for the alternate pattern which takes O(logn) time as logn is the number of bits used to represent that number. Thus total time is O(logn + logn + ? n times) = O(nlogn)
Space Complexity ? O(1) as no extra space is used.
Approach 2: Generate the Numbers From 1
An optimized and better approach to the problem would be to start with the first number having an alternate pattern and then consecutively alternately add 0s and 1s.
For adding 0 on the right side, use the left shift operator.
For adding 1 on the right side, use the left shift first and then add 1 using the XOR operator.
Pseudocode ?
procedure addZero (pass)
pass = pass << 1
ans = pass
end procedure
procedure addOne (pass)
pass = pass << 1
pass = pass ^ 1
ans = pass
end procedure
procedure numbers (N)
ans []
int num = 1
ans.add (num)
while (1)
num = addZero (num)
if (num > N)
break
else
ans.add (num)
end if
num = addOne (num)
if (num > N)
break
else
ans.add (num)
end if
end while
end procedure
Example
In the following program, addZero() function adds 0 at the LSB position and addOne() function adds 1 at the LSB position.
#include <bits/stdc++.h>
using namespace std;
int addZero(int pass){
// Left shift puts 0 at LSB position
pass = pass << 1;
return pass;
}
int addOne(int pass){
// Left shift puts 0 at LSB position
pass = pass << 1;
// XOR with 1 sets the LSB position
pass = pass ^ 1;
return pass;
}
vector<int> numbers(int N){
// Initializing an array to add numbers with alternate bit pattern
vector<int> ans;
// First number with alternate bit pattern is 1
int num = 1;
ans.push_back(num);
while (1) {
num = addZero(num);
// If on adding 0, num is greater than N then leave loop
if (num > N) {
break;
}
else{
ans.push_back(num);
}
num = addOne(num);
// If on adding 1, num is greater than N then leave loop
if (num > N){
break;
}
else{
ans.push_back(num);
}
}
return ans;
}
int main(){
int N = 50;
cout << "Numbers in range 1 to " << N << " having alternate bit pattern : ";
vector<int> res = numbers(N);
for (int i = 0; i < res.size(); i++){
cout << res[i] << " ";
}
return 0;
}
Output
Numbers in range 1 to 50 having alternate bit pattern : 1 2 5 10 21 42
Time Complexity ? O(logn)
Space Complexity ? O(1)
Conclusion
In conclusion, for finding the numbers with alternate bit pattern an optimised approach will be to produce numbers itself from 1 by left shifting and then setting and unsetting the LSB position. This approach is the most optimized and optimal.