Given an integer N, the task is to find the number of steps required to reduce the given number N to 1 by performing the following operations:
- If the number is a power of 2, then divide the number by 2.
- Otherwise, subtract the greatest power of 2 smaller than N from N.
Examples:
Input: N = 2
Output: 1
Explanation: The given number can be reduced to 1 by following the following steps:
Divide the number by 2 as N is a power of 2 which modifies the N to 1.
Therefore, the N can be reduced to 1 in only 1 step.Input: N = 7
Output: 2
Explanation: The given number can be reduced to 1 by following the following steps:
Subtract 4 the greatest power of 2 less than N. After the step the N modifies to N = 7-4 = 3.
Subtract 2 the greatest power of 2 less than N. After the step the N modifies to N = 3-2 = 1.
Therefore, the N can be reduced to 1 in 2 steps.
Method 1 –
Approach: The idea is to recursively compute the minimum number of steps required.
- If the number is a power of 2, then we are allowed to only divide the number by 2.
- Else we can subtract the greatest power of 2 smaller than N from N.
- So, we will use recursion for both the operations whenever valid and return number of operations.
Below is the implementation of the above approach:
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Utility function to check
// if n is power of 2
int highestPowerof2(int n)
{
int p = (int)log2(n);
return (int)pow(2, p);
}
// Utility function to find highest
// power of 2 less than or equal
// to given number
bool isPowerOfTwo(int n)
{
if(n==0)
return false;
return (ceil(log2(n)) == floor(log2(n)));
}
// Recursive function to find
// steps needed to reduce
// a given integer to 1
int reduceToOne(int N)
{
// Base Condition
if(N == 1){
return 0;
}
// If the number is a power of 2
if(isPowerOfTwo(N) == true){
return 1 + reduceToOne(N/2);
}
// Else subtract the greatest
//power of 2 smaller than N
//from N
else{
return 1 + reduceToOne(N - highestPowerof2(N));
}
}
// Driver Code
int main()
{
// Input
int N = 7;
// Function call
cout << reduceToOne(N) << endl;
}
// java program for the above approach
class GFG {
// Utility function to check
// if n is power of 2
static int highestPowerof2(int n)
{
int p = (int)(Math.log(n) / Math.log(2));
return (int)Math.pow(2, p);
}
// Utility function to find highest
// power of 2 less than or equal
// to given number
static boolean isPowerOfTwo(int n)
{
if(n==0)
return false;
return (int)(Math.ceil((Math.log(n) / Math.log(2)))) ==
(int)(Math.floor(((Math.log(n) / Math.log(2)))));
}
// Recursive function to find
// steps needed to reduce
// a given integer to 1
static int reduceToOne(int N)
{
// Base Condition
if(N == 1){
return 0;
}
// If the number is a power of 2
if(isPowerOfTwo(N) == true){
return 1 + reduceToOne(N/2);
}
// Else subtract the greatest
//power of 2 smaller than N
//from N
else{
return 1 + reduceToOne(N - highestPowerof2(N));
}
}
// Driver Code
public static void main(String [] args)
{
// Input
int N = 7;
// Function call
System.out.println(reduceToOne(N));
}
}
// This code is contributed by ihritik
# Python program for the above approach
import math
# Utility function to check
# Log base 2
def Log2(x):
if x == 0:
return false;
return (math.log10(x) /
math.log10(2));
# Utility function to check
# if x is power of 2
def isPowerOfTwo(n):
return (math.ceil(Log2(n)) ==
math.floor(Log2(n)));
# Utility function to find highest
# power of 2 less than or equal
# to given number
def highestPowerof2(n):
p = int(math.log(n, 2));
return int(pow(2, p));
# Recursive function to find
# steps needed to reduce
# a given integer to 1
def reduceToOne(N):
# Base Condition
if(N == 1):
return 0
# If the number is a power of 2
if(isPowerOfTwo(N) == True):
return 1 + reduceToOne(N/2)
# Else subtract the greatest
# power of 2 smaller than N
# from N
else:
return 1 + reduceToOne(N - highestPowerof2(N))
# Driver Code
# Input
N = 7;
#Function call
print(reduceToOne(N))
# This code is contributed by Samim Hossain Mondal.
// C# program for the above approach
using System;
class GFG {
// Utility function to check
// if n is power of 2
static int highestPowerof2(int n)
{
int p = (int)(Math.Log(n) / Math.Log(2));
return (int)Math.Pow(2, p);
}
// Utility function to find highest
// power of 2 less than or equal
// to given number
static bool isPowerOfTwo(int n)
{
if(n == 0)
return false;
return (int)(Math.Ceiling((Math.Log(n) / Math.Log(2)))) ==
(int)(Math.Floor(((Math.Log(n) / Math.Log(2)))));
}
// Recursive function to find
// steps needed to reduce
// a given integer to 1
static int reduceToOne(int N)
{
// Base Condition
if(N == 1){
return 0;
}
// If the number is a power of 2
if(isPowerOfTwo(N) == true){
return 1 + reduceToOne(N/2);
}
// Else subtract the greatest
//power of 2 smaller than N
//from N
else{
return 1 + reduceToOne(N - highestPowerof2(N));
}
}
// Driver Code
public static void Main()
{
// Input
int N = 7;
// Function call
Console.Write(reduceToOne(N));
}
}
// This code is contributed by Samim Hossain Mondal.
<script>
// Javascript program for the above approach
// Utility function to check
// if n is power of 2
function isPowerOfTwo(n)
{
if (n == 0)
return false;
return parseInt( (Math.ceil((Math.log(n) / Math.log(2))))) == parseInt( (Math.floor(((Math.log(n) / Math.log(2))))));
}
// Utility function to find highest
// power of 2 less than or equal
// to given number
function highestPowerof2(n)
{
let p = parseInt(Math.log(n) / Math.log(2), 10);
return Math.pow(2, p);
}
// Recursive function to find
// steps needed to reduce
// a given integer to 1
function reduceToOne(N)
{
// Base Condition
if(N == 1){
return 0;
}
// If the number is a power of 2
if(isPowerOfTwo(N) == true){
return 1 + reduceToOne(N/2);
}
// Else subtract the greatest
//power of 2 smaller than N
//from N
else{
return 1 + reduceToOne(N - highestPowerof2(N));
}
}
// Driver Code
// Input
let N = 7;
// Function call
document.write(reduceToOne(N));
// This code is contributed by Samim Hossain Mondal
</script>
Output
2
Method 2 –
Approach: The given problem can be solved using bitwise operators. Follow the steps below to solve the problem:
- Initialize two variables say res with value 0 and MSB with value log2(N) to store the number of steps needed to reduce the number to 1 and the most significant bit of N.
- Iterate while N is not equal to 1:
- Check if the number is the power of 2 then divide N by 2.
- Otherwise, subtract the largest power of 2 less than N from N i.e update N as N=N-2MSB.
- Increment res by 1 and decrement MSB by 1.
- Finally, print res.
Below is the implementation of the above approach:
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to find steps needed to
// reduce a given integer to 1
int reduceToOne(int N)
{
// Stores the most
// significant bit of N
int MSB = log2(N);
// Stores the number of steps
// required to reduce N to 1
int res = 0;
// Iterates while N
// is not equal 1
while (N != 1) {
// Increment res by 1
res++;
// If N is power of 2
if (N & (N - 1) == 0) {
// Divide N by 2
N /= 2;
}
// Otherwise
else {
// Subtract 2 ^ MSB
// from N
N -= (1 << MSB);
}
// Decrement MSB by 1
MSB--;
}
// Returns res
return res;
}
// Driver code
int main()
{
// Input
int N = 7;
// Function call
cout << reduceToOne(N) << endl;
}
/*package whatever //do not write package name here */
import java.io.*;
class GFG {
public static int logarithm(int number, int base)
{
int res = (int)(Math.log(number) / Math.log(base));
return res;
}
public static int reduceToOne(int N)
{
// Stores the most
// significant bit of N
int MSB = logarithm(N, 2);
// Stores the number of steps
// required to reduce N to 1
int res = 0;
// Iterates while N
// is not equal 1
while (N != 1) {
// Increment res by 1
res++;
// If N is power of 2
if ((N & (N - 1)) == 0) {
// Divide N by 2
N /= 2;
}
// Otherwise
else {
// Subtract 2 ^ MSB
// from N
N -= (1 << MSB);
}
// Decrement MSB by 1
MSB--;
}
// Returns res
return res;
}
public static void main(String[] args)
{
int N = 7;
int res = reduceToOne(N);
System.out.println(res);
}
}
// This code is contributed by lokeshpotta20.
# Python program for the above approach
import math
# Function to find steps needed to
# reduce a given integer to 1
def reduceToOne(N):
# Stores the most
# significant bit of N
MSB = math.floor(math.log2(N))
# Stores the number of steps
# required to reduce N to 1
res = 0
# Iterates while N
# is not equal 1
while (N != 1):
# Increment res by 1
res += 1
# If N is power of 2
if (N & (N - 1) == 0):
# Divide N by 2
N //= 2
# Otherwise
else:
# Subtract 2 ^ MSB
# from N
N -= (1 << MSB)
# Decrement MSB by 1
MSB-=1
# Returns res
return res
# Driver code
# Input
N = 7
# Function call
print(reduceToOne(N))
# This code is contributed by shubham Singh
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find steps needed to
// reduce a given integer to 1
static int reduceToOne(int N)
{
// Stores the most
// significant bit of N
int MSB = (int)(Math.Log(N)/Math.Log(2));
// Stores the number of steps
// required to reduce N to 1
int res = 0;
// Iterates while N
// is not equal 1
while (N != 1) {
// Increment res by 1
res++;
// If N is power of 2
if ((N & (N - 1)) == 0) {
// Divide N by 2
N /= 2;
}
// Otherwise
else {
// Subtract 2 ^ MSB
// from N
N -= (1 << MSB);
}
// Decrement MSB by 1
MSB--;
}
// Returns res
return res;
}
// Driver code
public static void Main()
{
// Input
int N = 7;
// Function call
Console.Write(reduceToOne(N));
}
}
// This code is contributed by bgangwar59.
<script>
// JavaScript program for the above approach
function logarithm(number, base)
{
let res = (Math.log(number) / Math.log(base));
return res;
}
function reduceToOne(N)
{
// Stores the most
// significant bit of N
let MSB = logarithm(N, 2);
// Stores the number of steps
// required to reduce N to 1
let res = 0;
// Iterates while N
// is not equal 1
while (N != 1) {
// Increment res by 1
res++;
// If N is power of 2
if ((N & (N - 1)) == 0) {
// Divide N by 2
N /= 2;
}
// Otherwise
else {
// Subtract 2 ^ MSB
// from N
N -= (1 << MSB);
}
// Decrement MSB by 1
MSB--;
}
// Returns res
return res;
}
// Driver Code
let N = 7;
let res = reduceToOne(N);
document.write(res);
</script>
Output
2
Time Complexity: O(log(N))
Auxiliary Space: O(1)