@@ -26,84 +26,73 @@ private static NextLargerAndSmallerNumber getNextLargerAndSmallerNumber(int n) {
2626 }
2727
2828 private static int getNextLarger (int n ) {
29- int zeroPrecededByOneFromRight = 0 ;
29+ int rightmostNonTrailingZero = 0 ;
30+ int noOfZeros = 0 ;
3031 int noOfOnes = 0 ;
31- int mask = 1 ;
32+ int temp = n ;
3233
33- /* Find the position of the bit pattern '01' from the right and then make it '10'.
34- For example, see below:
34+ /* Count the number of zeros and ones until the rightmost non-trailing zero
35+ For example, see below:
3536
3637 n = 10110110011110
37- ^^
38- n = 10110110101110 (after bit swap)
38+ ^
3939 */
40- for (int i = 0 ; i < Integer .BYTES * 8 - 1 ; i ++) {
41- if ((n & mask ) == mask ) {
42- if ((n & mask << 1 ) == 0 ) {
43- n = (n & ~mask ) | mask << 1 ; // swap the bits
44- break ;
45- }
46- noOfOnes ++;
47- }
48- zeroPrecededByOneFromRight ++;
49- mask <<= 1 ;
40+ while ((temp & 1 ) == 0 && temp != 0 ) {
41+ noOfZeros ++;
42+ temp >>>= 1 ;
5043 }
5144
52- if (zeroPrecededByOneFromRight == Integer .BYTES * 8 - 1 ) {
45+ while ((temp & 1 ) == 1 && temp != 0 ) {
46+ noOfOnes ++;
47+ temp >>>= 1 ;
48+ }
49+
50+ if (noOfZeros + noOfOnes == 31 || noOfZeros + noOfOnes == 0 ) {
5351 return -1 ;
5452 }
5553
56- /* Shift all the 1s to the right end and then fill with 0s until the bit pattern '01.
54+ /* Flip the bit and then shift all the 1s to the right end and then fill with 0s until the bit pattern '01.
5755 For example, consider the above number:
58-
59- n = 10110110101110 (after bit swap)
60- ^^
61- next larger = 10110110100111 (the 1s are shifted to the right end)
56+ n = 10110110011110 (original)
57+ ^
58+ n = 10110110111110 (after flip bit)
59+ ^
60+ next larger = 10110110100111 (the 1s are shifted to the right end and 0s to the left but before the rightmostNonTrailingZero)
61+ ^
6262 */
63- mask = 1 ;
64- for (int i = 0 ; i < zeroPrecededByOneFromRight ; i ++) {
65- if (i < noOfOnes ) {
66- n = n | mask ; // set the bits
67- } else {
68- n = n & ~mask ; // unset the bits
69- }
70- mask <<= 1 ;
71- }
63+ rightmostNonTrailingZero = noOfOnes + noOfZeros ;
64+ n |= 1 << rightmostNonTrailingZero ; // set the rightmost non-trailing zero
65+ n &= ~((1 << rightmostNonTrailingZero ) - 1 ); // unset all bits until rightmost non-trailing zero
66+ n |= (1 << noOfOnes - 1 ) - 1 ; // set (noOfOnes - 1) bits from the right
67+
7268 return n ;
7369 }
7470
7571 private static int getNextSmaller (int n ) {
76- int onePrecededByZeroFromRight = 0 ;
72+ int rightmostNonTrailingOne = 0 ;
7773 int noOfZeros = 0 ;
78- int mask = 1 ;
79-
80- // find the position of the bit pattern '10' from the right and then make it '01'
81- for (int i = 0 ; i < Integer .BYTES * 8 - 1 ; i ++) {
82- if ((n & mask ) == 0 ) {
83- if ((n & mask << 1 ) == mask << 1 ) {
84- n = (n | mask ) & ~(mask << 1 ); // swap the bits
85- break ;
86- }
87- noOfZeros ++;
88- }
89- onePrecededByZeroFromRight ++;
90- mask <<= 1 ;
74+ int noOfOnes = 0 ;
75+ int temp = n ;
76+
77+ while ((temp & 1 ) == 1 && temp != 0 ) {
78+ noOfOnes ++;
79+ temp >>>= 1 ;
9180 }
92-
93- if (onePrecededByZeroFromRight == Integer . BYTES * 8 - 1 ) {
81+
82+ if (temp == 0 ) {
9483 return -1 ;
9584 }
9685
97- // shift all the 0s to the right end and then fill with 1s until the bit pattern '10'
98- mask = 1 ;
99- for (int i = 0 ; i < onePrecededByZeroFromRight ; i ++) {
100- if (i < noOfZeros ) {
101- n = n & ~mask ; // unset the bits
102- } else {
103- n = n | mask ; // set the bits
104- }
105- mask <<= 1 ;
86+ while ((temp & 1 ) == 0 && temp != 0 ) {
87+ noOfZeros ++;
88+ temp >>>= 1 ;
10689 }
90+
91+ rightmostNonTrailingOne = noOfZeros + noOfOnes ;
92+ n &= ~(1 << rightmostNonTrailingOne ); // unset the rightmost non-trailing one
93+ n |= (1 << rightmostNonTrailingOne - 1 ); // set all the bits until rightmost non-trailing one
94+ n &= ~((1 << noOfZeros - 1 ) - 1 ); // unset (noOfZeros - 1) bits from the right
95+
10796 return n ;
10897 }
10998
0 commit comments