给定一个正整数n,请打印在其二进制表示形式中具有相同的1位数字的下一个最小和前一个最大数字。
例子 :
Input : n = 5
Output : Closest Greater = 6
Closest Smaller = 3
Note that 5, 6 and 3 have same number of
set bits.
Input : n = 11
Output : Closest Greater = 13
Closest Smaller = 7
蛮力法
一种简单的方法就是蛮力:计算n中1的数量,然后递增(或递减)直到找到相同的1。
最佳方法
让我们从getNext的代码开始,然后继续进行getPrev。
获取下一个数字的位操作方法
如果我们考虑下一个数字应该是什么,我们可以观察到以下内容。给定数字13948,二进制表示形式如下:
1 1 0 1 1 0 0 1 1 1 1 1 0 0
13 12 11 10 9 8 7 6 5 4 3 2 1 0
我们希望使这个数字更大(但不要太大)。我们还需要保持相同数量。
观察:给定一个数字n和两个比特位置i和j,假设我们将比特i从1翻转到0,将比特j从0翻转到1。如果i> j,则n将减少。如果i
- 如果将0翻转为1,则必须将1翻转为零。
- 该数字(两次翻转后)将更大,且仅当零比一位在一位至零位的左侧时才如此。
- 我们希望使数字更大,但不必不必要地更大。因此,我们需要翻转最右边的零(在右边有一个零)。
换句话说,我们将最右边的非尾随零翻转。也就是说,使用上面的示例,尾随零在第0和第1点。最右边的非拖尾零在位7处。我们将此位置称为p。
p ==> Position of rightmost non-trailing 0.
步骤1:翻转最右边的非尾随零
1 1 0 1 1 0 1 1 1 1 1 1 0 0
13 12 11 10 9 8 7 6 5 4 3 2 1 0
通过此更改,我们增加了n的1的数量。我们可以通过将所有位重新排列到位p的右边来缩小数字,以使0在左边,而1在右边。这样做时,我们想用0代替1中的一个。
一个相对简单的方法是计算p右边的个数,清除从0到p的所有位,然后加回c1-1。令c1是p右边的1的数目,而c0是p右边的零的数目。
让我们通过一个例子来完成这个过程。
c1 ==> Number of ones to the right of p
c0 ==> Number of zeros to the right of p.
p = c0 + c1
步骤2:清除p右侧的位。从之前开始,c0 =2。c1=5。p= 7。
1 1 0 1 1 0 1 0 0 0 0 0 0 0
13 12 11 10 9 8 7 6 5 4 3 2 1 0
要清除这些位,我们需要创建一个掩码,该掩码为一串序列,后跟p个零。我们可以这样做,如下所示:
// all zeros except for a 1 at position p.
a = 1 << p;
// all zeros, followed by p ones.
b = a - 1;
// all ones, followed by p zeros.
mask = ~b;
// clears rightmost p bits.
n = n & mask;
Or, more concisely, we do:
n &= ~((1 << p) - 1).
步骤3:添加一个c1-1。
1 1 0 1 1 0 1 0 0 0 1 1 1 1
13 12 11 10 9 8 7 6 5 4 3 2 1 0
要在右侧插入c1 – 1,我们执行以下操作:
// 0s with a 1 at position c1– 1
a = 1 << (c1 - 1);
// 0s with 1s at positions 0 through c1-1
b = a - 1;
// inserts 1s at positions 0 through c1-1
n = n | b;
Or, more concisely:
n | = (1 << (c1 - 1)) - 1;
现在,我们得出了具有相同数目的大于n的最小数目。 getNext的代码实现如下
C++
// C++ implementation of getNext with
// same number of bits 1's is below
#include
using namespace std;
// Main Function to find next smallest
// number bigger than n
int getNext(int n)
{
/* Compute c0 and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0))
{
c0 ++;
c >>= 1;
}
while ((c & 1)==1)
{
c1++;
c >>= 1;
}
// If there is no bigger number with the
// same no. of 1's
if (c0 +c1 == 31 || c0 +c1== 0)
return -1;
// position of rightmost non-trailing zero
int p = c0 + c1;
// Flip rightmost non-trailing zero
n |= (1 << p);
// Clear all bits to the right of p
n &= ~((1 << p) - 1);
// Insert (c1-1) ones on the right.
n |= (1 << (c1 - 1)) - 1;
return n;
}
// Driver Code
int main()
{
int n = 5; // input 1
cout << getNext(n) << endl;
n = 8; // input 2
cout << getNext(n);
return 0;
}
Java
// Java implementation of
// getNext with same number
// of bits 1's is below
import java.io.*;
class GFG
{
// Main Function to find next
// smallest number bigger than n
static int getNext(int n)
{
/* Compute c0 and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) &&
(c != 0))
{
c0++;
c >>= 1;
}
while ((c & 1) == 1)
{
c1++;
c >>= 1;
}
// If there is no bigger number
// with the same no. of 1's
if (c0 + c1 == 31 ||
c0 + c1 == 0)
return -1;
// position of rightmost
// non-trailing zero
int p = c0 + c1;
// Flip rightmost
// non-trailing zero
n |= (1 << p);
// Clear all bits
// to the right of p
n &= ~((1 << p) - 1);
// Insert (c1-1) ones
// on the right.
n |= (1 << (c1 - 1)) - 1;
return n;
}
// Driver Code
public static void main (String[] args)
{
int n = 5; // input 1
System.out.println(getNext(n));
n = 8; // input 2
System.out.println(getNext(n));
}
}
// This code is contributed by aj_36
Python 3
# Python 3 implementation of getNext with
# same number of bits 1's is below
# Main Function to find next smallest
# number bigger than n
def getNext(n):
# Compute c0 and c1
c = n
c0 = 0
c1 = 0
while (((c & 1) == 0) and (c != 0)):
c0 += 1
c >>= 1
while ((c & 1) == 1):
c1 += 1
c >>= 1
# If there is no bigger number with
# the same no. of 1's
if (c0 + c1 == 31 or c0 + c1== 0):
return -1
# position of rightmost non-trailing zero
p = c0 + c1
# Flip rightmost non-trailing zero
n |= (1 << p)
# Clear all bits to the right of p
n &= ~((1 << p) - 1)
# Insert (c1-1) ones on the right.
n |= (1 << (c1 - 1)) - 1
return n
# Driver Code
if __name__ == "__main__":
n = 5 # input 1
print(getNext(n))
n = 8 # input 2
print(getNext(n))
# This code is contributed by ita_c
C#
// C# implementation of getNext with
// same number of bits 1's is below
using System;
class GFG {
// Main Function to find next
// smallest number bigger than n
static int getNext(int n)
{
/* Compute c0 and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0))
{
c0++;
c >>= 1;
}
while ((c & 1) == 1)
{
c1++;
c >>= 1;
}
// If there is no bigger number
// with the same no. of 1's
if (c0 + c1 == 31 || c0 + c1== 0)
return -1;
// position of rightmost
// non-trailing zero
int p = c0 + c1;
// Flip rightmost non-trailing
// zero
n |= (1 << p);
// Clear all bits to the right
// of p
n &= ~((1 << p) - 1);
// Insert (c1-1) ones on the
// right.
n |= (1 << (c1 - 1)) - 1;
return n;
}
// Driver Code
static void Main()
{
int n = 5; // input 1
Console.WriteLine(getNext(n));
n = 8; // input 2
Console.Write(getNext(n));
}
}
// This code is contributed by Anuj_67
PHP
>= 1;
}
while (($c & 1) == 1)
{
$c1++;
$c >>= 1;
}
// If there is no bigger
// number with the
// same no. of 1's
if ($c0 + $c1 == 31 ||
$c0 + $c1== 0)
return -1;
// position of rightmost
// non-trailing zero
$p = $c0 + $c1;
// Flip rightmost non -
// trailing zero
$n |= (1 << $p);
// Clear all bits to
// the right of p
$n &= ~((1 << $p) - 1);
// Insert (c1-1) ones
// on the right.
$n |= (1 << ($c1 - 1)) - 1;
return $n;
}
// Driver Code
// input 1
$n = 5;
echo getNext($n),"\n";
// input 2
$n = 8;
echo getNext($n);
// This code is contributed by ajit
?>
Javascript
C++
// C++ Implementation of getPrev in
// Same number of bits 1's is below
#include
using namespace std;
// Main Function to find next Bigger number
// Smaller than n
int getPrev(int n)
{
/* Compute c0 and c1 and store N*/
int temp = n;
int c0 = 0;
int c1= 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) && (temp!= 0))
{
c0++;
temp = temp >> 1;
}
// position of rightmost non-trailing one.
int p = c0 + c1;
// clears from bit p onwards
n = n & ((~0) << (p + 1));
// Sequence of (c1+1) ones
int mask = (1 << (c1 + 1)) - 1;
n = n | mask << (c0 - 1);
return n;
}
// Driver Code
int main()
{
int n = 6; // input 1
cout << getPrev(n);
n = 16; // input 2
cout << endl;
cout << getPrev(n);
return 0;
}
Java
// Java Implementation of
// getPrev in Same number
// of bits 1's is below
import java.io.*;
class GFG
{
// Main Function to find
// next Bigger number
// Smaller than n
static int getPrev(int n)
{
// Compute c0 and
// c1 and store N
int temp = n;
int c0 = 0;
int c1= 0;
while((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if(temp == 0)
return -1;
while(((temp & 1) == 0) &&
(temp!= 0))
{
c0++;
temp = temp >> 1;
}
// position of rightmost
// non-trailing one.
int p = c0 + c1;
// clears from bit p onwards
n = n & ((~0) << (p + 1));
// Sequence of (c1+1) ones
int mask = (1 << (c1 + 1)) - 1;
n = n | mask << (c0 - 1);
return n;
}
// Driver Code
public static void main(String[] args)
{
int n = 6; // input 1
System.out.println(getPrev(n));
n = 16; // input 2
System.out.println(getPrev(n));
}
}
// This code is contributed by aj_36
C#
// C# Implementation of
// getPrev in Same number
// of bits 1's is below
using System;
class GFG
{
// Main Function to find
// next Bigger number
// Smaller than n
static int getPrev(int n)
{
// Compute c0 and
// c1 and store N
int temp = n;
int c0 = 0;
int c1 = 0;
while((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if(temp == 0)
return -1;
while(((temp & 1) == 0) &&
(temp != 0))
{
c0++;
temp = temp >> 1;
}
// position of rightmost
// non-trailing one.
int p = c0 + c1;
// clears from
// bit p onwards
n = n & ((~0) << (p + 1));
// Sequence of
// (c1+1) ones
int mask = (1 << (c1 + 1)) - 1;
n = n | mask << (c0 - 1);
return n;
}
// Driver Code
static public void Main ()
{
int n = 6; // input 1
Console.WriteLine(getPrev(n));
n = 16; // input 2
Console.WriteLine(getPrev(n));
}
}
// This code is contributed by ajit
PHP
> 1;
}
if ($temp == 0)
return -1;
while ((($temp & 1) == 0) &&
($temp!= 0))
{
$c0++;
$temp = $temp >> 1;
}
// position of rightmost
// non-trailing one.
$p = $c0 + $c1;
// clears from bit p onwards
$n = $n & ((~0) << ($p + 1));
// Sequence of (c1 + 1) ones
$mask = (1 << ($c1 + 1)) - 1;
$n = $n | $mask << ($c0 - 1);
return $n;
}
// Driver Code
// input 1
$n = 6;
echo getPrev($n);
// input 2
$n = 16;
echo " \n" ;
echo getPrev($n);
// This code is contributed by Ajit
?>
Javascript
C++
// C++ Implementation of getNext with
// Same number of bits 1's is below
#include
using namespace std;
// Main Function to find next smallest number
// bigger than n
int getNext(int n)
{
/* Compute c0 and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0))
{
c0 ++;
c >>= 1;
}
while ((c & 1)==1)
{
c1++;
c >>= 1;
}
// If there is no bigger number with the
// same no. of 1's
if (c0 +c1 == 31 || c0 +c1== 0)
return -1;
return n + (1 << c0) + (1 << (c1 - 1)) - 1;
}
// Driver Code
int main()
{
int n = 5; // input 1
cout << getNext(n);
n = 8; // input 2
cout << endl;
cout << getNext(n);
return 0;
}
Java
// Java Implementation of getNext with
// Same number of bits 1's is below
import java.io.*;
class GFG
{
// Function to find next smallest
// number bigger than n
static int getNext(int n)
{
/* Compute c0
and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0))
{
c0 ++;
c >>= 1;
}
while ((c & 1) == 1)
{
c1++;
c >>= 1;
}
// If there is no bigger number
// with the same no. of 1's
if (c0 + c1 == 31 || c0 + c1 == 0)
return -1;
return n + (1 << c0) +
(1 << (c1 - 1)) - 1;
}
// Driver Code
public static void main (String[] args)
{
int n = 5; // input 1
System.out.println(getNext(n));
n = 8; // input 2
System.out.println(getNext(n));
}
}
// This code is contributed by ajit
C#
// C# Implementation of getNext
// with Same number of bits
// 1's is below
using System;
class GFG
{
// Function to find next smallest
// number bigger than n
static int getNext(int n)
{
/* Compute c0
and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) &&
(c != 0))
{
c0 ++;
c >>= 1;
}
while ((c & 1) == 1)
{
c1++;
c >>= 1;
}
// If there is no bigger
// number with the same
// no. of 1's
if (c0 + c1 == 31 ||
c0 + c1 == 0)
return -1;
return n + (1 << c0) +
(1 << (c1 - 1)) - 1;
}
// Driver Code
static public void Main ()
{
int n = 5; // input 1
Console.WriteLine(getNext(n));
n = 8; // input 2
Console.WriteLine(getNext(n));
}
}
// This code is contributed by m_kit
PHP
>= 1;
}
while (($c & 1) == 1)
{
$c1++;
$c >>= 1;
}
// If there is no bigger
// number with the
// same no. of 1's
if ($c0 + $c1 == 31 ||
$c0 + $c1 == 0)
return -1;
return $n + (1 << $c0) +
(1 << ($c1 - 1)) - 1;
}
// Driver Code
$n = 5; // input 1
echo getNext($n);
$n = 8; // input 2
echo "\n";
echo getNext($n);
// This code is contributed by ajit
?>
C++
// C++ Implementation of Arithmetic Approach to
// getPrev with Smae number of bits 1's is below
#include
using namespace std;
// Main Function to find next Bigger number
// Smaller than n
int getPrev(int n)
{
/* Compute c0 and c1 and store N*/
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) && (temp!= 0))
{
c0++;
temp = temp >> 1;
}
return n - (1 << c1) - (1 << (c0 - 1)) + 1;
}
// Driver Code
int main()
{
int n = 6; // input 1
cout << getPrev(n);
n = 16; // input 2
cout << endl;
cout << getPrev(n);
return 0;
}
Java
// Java Implementation of Arithmetic
// Approach to getPrev with Same
// number of bits 1's is below
import java.io.*;
class GFG
{
// Main Function to find next
// Bigger number Smaller than n
static int getPrev(int n)
{
/* Compute c0 and
c1 and store N*/
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) &&
(temp!= 0))
{
c0++;
temp = temp >> 1;
}
return n - (1 << c1) -
(1 << (c0 - 1)) + 1;
}
// Driver Code
public static void main (String[] args)
{
int n = 6; // input 1
System.out.println (getPrev(n));
n = 16; // input 2
System.out.println(getPrev(n));
}
}
// This code is contributed by akt_mit
Python3
# Python3 Implementation of Arithmetic Approach to
# getPrev with Smae number of bits 1's is below
# Main Function to find next Bigger
# number Smaller than n
def getPrev(n):
# Compute c0 and c1 and store N
temp = n
c0 = 0
c1 = 0
while ((temp & 1) == 1):
c1 += 1
temp = temp >> 1
if (temp == 0):
return -1
while (((temp & 1) == 0) and (temp != 0)):
c0 += 1
temp = temp >> 1
return n - (1 << c1) - (1 << (c0 - 1)) + 1
# Driver Code
if __name__ == '__main__':
n = 6 # input 1
print(getPrev(n))
n = 16 # input 2
print(getPrev(n))
# This code is contributed
# by PrinciRaj1992
C#
// C# Implementation of Arithmetic
// Approach to getPrev with Same
// number of bits 1's is below
using System;
class GFG
{
// Main Function to find next
// Bigger number Smaller than n
static int getPrev(int n)
{
/* Compute c0 and
c1 and store N*/
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) &&
(temp!= 0))
{
c0++;
temp = temp >> 1;
}
return n - (1 << c1) -
(1 << (c0 - 1)) + 1;
}
// Driver Code
static public void Main ()
{
int n = 6; // input 1
Console.WriteLine(getPrev(n));
n = 16; // input 2
Console.WriteLine(getPrev(n));
}
}
// This code is contributed by ajit
PHP
输出:
6
16
获取上一个号码的最佳位处理方法
要实现getPrev,我们遵循非常相似的方法。
- 计算c0和c1。请注意, c1是尾随的1的数量,而c0是尾随的1左侧紧随其后的零块的大小。
- 将最右边的非拖尾的1翻转为零。这将在位置p = c1 + c0处。
- 清除位p右边的所有位。
- 在位置p的右边立即插入c1 + 1。
请注意,第2步将位p设置为零,而第3步将位0到p-1设置为零。我们可以合并这些步骤。
让我们通过一个例子来完成这个过程。
c1 ==> number of trailing ones
c0 ==> size of the block of zeros immediately
to the left of the trailing ones.
p = c1 + c0
步骤1:初始编号:p =7。c1=2。c0= 5。
1 0 0 1 1 1 1 0 0 0 0 0 1 1
13 12 11 10 9 8 7 6 5 4 3 2 1 0
步骤2和3:清除位0到p。
1 0 0 1 1 1 0 0 0 0 0 0 0 0
13 12 11 10 9 8 7 6 5 4 3 2 1 0
我们可以这样做,如下所示:
// Sequence of 1s
int a = ~0;
// Sequence of 1s followed by p + 1 zeros.
int b = a << (p + 1);
// Clears bits 0 through p.
n & = b;
步骤4:在位置p的右边立即插入c1 + 1。
1 0 0 1 1 1 0 1 1 1 0 0 0 0
13 12 11 10 9 8 7 6 5 4 3 2 1 0
请注意,由于p = c1 + c0,因此(c1 + 1)后面将是(c0 – 1)零。
我们可以这样做,如下所示:
// 0s with 1 at position (c1 + 1)
int a = 1 << (c1 + 1);
// 0s followed by c1 + 1 ones
int b = a - 1;
// c1 + 1 ones followed by c0 - 1 zeros.
int c = b << (c0 - 1);
n |= c;
下面是实现此目的的代码。
C++
// C++ Implementation of getPrev in
// Same number of bits 1's is below
#include
using namespace std;
// Main Function to find next Bigger number
// Smaller than n
int getPrev(int n)
{
/* Compute c0 and c1 and store N*/
int temp = n;
int c0 = 0;
int c1= 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) && (temp!= 0))
{
c0++;
temp = temp >> 1;
}
// position of rightmost non-trailing one.
int p = c0 + c1;
// clears from bit p onwards
n = n & ((~0) << (p + 1));
// Sequence of (c1+1) ones
int mask = (1 << (c1 + 1)) - 1;
n = n | mask << (c0 - 1);
return n;
}
// Driver Code
int main()
{
int n = 6; // input 1
cout << getPrev(n);
n = 16; // input 2
cout << endl;
cout << getPrev(n);
return 0;
}
Java
// Java Implementation of
// getPrev in Same number
// of bits 1's is below
import java.io.*;
class GFG
{
// Main Function to find
// next Bigger number
// Smaller than n
static int getPrev(int n)
{
// Compute c0 and
// c1 and store N
int temp = n;
int c0 = 0;
int c1= 0;
while((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if(temp == 0)
return -1;
while(((temp & 1) == 0) &&
(temp!= 0))
{
c0++;
temp = temp >> 1;
}
// position of rightmost
// non-trailing one.
int p = c0 + c1;
// clears from bit p onwards
n = n & ((~0) << (p + 1));
// Sequence of (c1+1) ones
int mask = (1 << (c1 + 1)) - 1;
n = n | mask << (c0 - 1);
return n;
}
// Driver Code
public static void main(String[] args)
{
int n = 6; // input 1
System.out.println(getPrev(n));
n = 16; // input 2
System.out.println(getPrev(n));
}
}
// This code is contributed by aj_36
C#
// C# Implementation of
// getPrev in Same number
// of bits 1's is below
using System;
class GFG
{
// Main Function to find
// next Bigger number
// Smaller than n
static int getPrev(int n)
{
// Compute c0 and
// c1 and store N
int temp = n;
int c0 = 0;
int c1 = 0;
while((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if(temp == 0)
return -1;
while(((temp & 1) == 0) &&
(temp != 0))
{
c0++;
temp = temp >> 1;
}
// position of rightmost
// non-trailing one.
int p = c0 + c1;
// clears from
// bit p onwards
n = n & ((~0) << (p + 1));
// Sequence of
// (c1+1) ones
int mask = (1 << (c1 + 1)) - 1;
n = n | mask << (c0 - 1);
return n;
}
// Driver Code
static public void Main ()
{
int n = 6; // input 1
Console.WriteLine(getPrev(n));
n = 16; // input 2
Console.WriteLine(getPrev(n));
}
}
// This code is contributed by ajit
的PHP
> 1;
}
if ($temp == 0)
return -1;
while ((($temp & 1) == 0) &&
($temp!= 0))
{
$c0++;
$temp = $temp >> 1;
}
// position of rightmost
// non-trailing one.
$p = $c0 + $c1;
// clears from bit p onwards
$n = $n & ((~0) << ($p + 1));
// Sequence of (c1 + 1) ones
$mask = (1 << ($c1 + 1)) - 1;
$n = $n | $mask << ($c0 - 1);
return $n;
}
// Driver Code
// input 1
$n = 6;
echo getPrev($n);
// input 2
$n = 16;
echo " \n" ;
echo getPrev($n);
// This code is contributed by Ajit
?>
Java脚本
输出 :
5
8
获取下一个数字的算术方法
如果c0是尾随零的数量,c1是紧随其后的1个块的大小,并且p = c0 + c1,我们可以从更早的时候形成我们的解决方案,如下所示:
- 将第p位设置为1。
- 将p之后的所有位设置为0。
- 将位0到c1 – 2设置为1。这将总计c1 – 1。
一种执行步骤1和2的快速方法是将尾随零设置为1(为我们提供p后随的数字),然后加1。加一将翻转所有尾随的1,因此我们在p位的末尾为1,然后是p p零。我们可以算术地执行此操作。
//将尾随0设置为1,为我们提供尾随1的p。
n + = 2 c0 – 1;
//将第一个p ls翻转为0s,并在p位置放置1。
n + = 1;
现在,要算术执行步骤3,我们只需执行以下操作:
//将尾随的c1 – 1零设置为1。
n + = 2 c1 – 1 – 1;
该数学公式简化为:
下一个= n +(2 c0 – 1)+ 1 +(2 c1 – 1 – 1)
= n + 2 c0 + 2 c1 – 1 – 1
最好的部分是,通过一点点操作,编写起来很简单。
C++
// C++ Implementation of getNext with
// Same number of bits 1's is below
#include
using namespace std;
// Main Function to find next smallest number
// bigger than n
int getNext(int n)
{
/* Compute c0 and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0))
{
c0 ++;
c >>= 1;
}
while ((c & 1)==1)
{
c1++;
c >>= 1;
}
// If there is no bigger number with the
// same no. of 1's
if (c0 +c1 == 31 || c0 +c1== 0)
return -1;
return n + (1 << c0) + (1 << (c1 - 1)) - 1;
}
// Driver Code
int main()
{
int n = 5; // input 1
cout << getNext(n);
n = 8; // input 2
cout << endl;
cout << getNext(n);
return 0;
}
Java
// Java Implementation of getNext with
// Same number of bits 1's is below
import java.io.*;
class GFG
{
// Function to find next smallest
// number bigger than n
static int getNext(int n)
{
/* Compute c0
and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) && (c != 0))
{
c0 ++;
c >>= 1;
}
while ((c & 1) == 1)
{
c1++;
c >>= 1;
}
// If there is no bigger number
// with the same no. of 1's
if (c0 + c1 == 31 || c0 + c1 == 0)
return -1;
return n + (1 << c0) +
(1 << (c1 - 1)) - 1;
}
// Driver Code
public static void main (String[] args)
{
int n = 5; // input 1
System.out.println(getNext(n));
n = 8; // input 2
System.out.println(getNext(n));
}
}
// This code is contributed by ajit
C#
// C# Implementation of getNext
// with Same number of bits
// 1's is below
using System;
class GFG
{
// Function to find next smallest
// number bigger than n
static int getNext(int n)
{
/* Compute c0
and c1 */
int c = n;
int c0 = 0;
int c1 = 0;
while (((c & 1) == 0) &&
(c != 0))
{
c0 ++;
c >>= 1;
}
while ((c & 1) == 1)
{
c1++;
c >>= 1;
}
// If there is no bigger
// number with the same
// no. of 1's
if (c0 + c1 == 31 ||
c0 + c1 == 0)
return -1;
return n + (1 << c0) +
(1 << (c1 - 1)) - 1;
}
// Driver Code
static public void Main ()
{
int n = 5; // input 1
Console.WriteLine(getNext(n));
n = 8; // input 2
Console.WriteLine(getNext(n));
}
}
// This code is contributed by m_kit
的PHP
>= 1;
}
while (($c & 1) == 1)
{
$c1++;
$c >>= 1;
}
// If there is no bigger
// number with the
// same no. of 1's
if ($c0 + $c1 == 31 ||
$c0 + $c1 == 0)
return -1;
return $n + (1 << $c0) +
(1 << ($c1 - 1)) - 1;
}
// Driver Code
$n = 5; // input 1
echo getNext($n);
$n = 8; // input 2
echo "\n";
echo getNext($n);
// This code is contributed by ajit
?>
输出 :
6
16
获取上一个数字的算术方法
如果c1是尾随的数字,c0是紧随其后的零块的大小,并且p = c0 + c1,我们可以用以下方式写出初始getPrev解决方案:
- 将pth位设置为0
- 将p之后的所有位设置为1
- 将位0到c0 – 1设置为0。
我们可以如下算术实现。为了示例清楚起见,我们假设n =10000011。这使c1 = 2和c0 = 5。
// Removes trailing 1s. n is now 10000000.
n -= 2c1 – 1;
// Flips trailing 0s. n is now 01111111.
n -= 1;
// Flips last (c0-1) 0s. n is now 01110000.
n -= 2c0 - 1 - 1;
This reduces mathematically to:
next = n - (2c1 - 1) - 1 - ( 2c0-1 - 1) .
= n - 2c1 - 2c0-1 + 1;
同样,这很容易实现。
C++
// C++ Implementation of Arithmetic Approach to
// getPrev with Smae number of bits 1's is below
#include
using namespace std;
// Main Function to find next Bigger number
// Smaller than n
int getPrev(int n)
{
/* Compute c0 and c1 and store N*/
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) && (temp!= 0))
{
c0++;
temp = temp >> 1;
}
return n - (1 << c1) - (1 << (c0 - 1)) + 1;
}
// Driver Code
int main()
{
int n = 6; // input 1
cout << getPrev(n);
n = 16; // input 2
cout << endl;
cout << getPrev(n);
return 0;
}
Java
// Java Implementation of Arithmetic
// Approach to getPrev with Same
// number of bits 1's is below
import java.io.*;
class GFG
{
// Main Function to find next
// Bigger number Smaller than n
static int getPrev(int n)
{
/* Compute c0 and
c1 and store N*/
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) &&
(temp!= 0))
{
c0++;
temp = temp >> 1;
}
return n - (1 << c1) -
(1 << (c0 - 1)) + 1;
}
// Driver Code
public static void main (String[] args)
{
int n = 6; // input 1
System.out.println (getPrev(n));
n = 16; // input 2
System.out.println(getPrev(n));
}
}
// This code is contributed by akt_mit
Python3
# Python3 Implementation of Arithmetic Approach to
# getPrev with Smae number of bits 1's is below
# Main Function to find next Bigger
# number Smaller than n
def getPrev(n):
# Compute c0 and c1 and store N
temp = n
c0 = 0
c1 = 0
while ((temp & 1) == 1):
c1 += 1
temp = temp >> 1
if (temp == 0):
return -1
while (((temp & 1) == 0) and (temp != 0)):
c0 += 1
temp = temp >> 1
return n - (1 << c1) - (1 << (c0 - 1)) + 1
# Driver Code
if __name__ == '__main__':
n = 6 # input 1
print(getPrev(n))
n = 16 # input 2
print(getPrev(n))
# This code is contributed
# by PrinciRaj1992
C#
// C# Implementation of Arithmetic
// Approach to getPrev with Same
// number of bits 1's is below
using System;
class GFG
{
// Main Function to find next
// Bigger number Smaller than n
static int getPrev(int n)
{
/* Compute c0 and
c1 and store N*/
int temp = n;
int c0 = 0;
int c1 = 0;
while ((temp & 1) == 1)
{
c1++;
temp = temp >> 1;
}
if (temp == 0)
return -1;
while (((temp & 1) == 0) &&
(temp!= 0))
{
c0++;
temp = temp >> 1;
}
return n - (1 << c1) -
(1 << (c0 - 1)) + 1;
}
// Driver Code
static public void Main ()
{
int n = 6; // input 1
Console.WriteLine(getPrev(n));
n = 16; // input 2
Console.WriteLine(getPrev(n));
}
}
// This code is contributed by ajit
的PHP
输出 :
5
8