CTCI: Ch. 5-3

Given a positive integer, print the next smallest and the next largest number that have the same number of 1 bits in their binary representation.

unsigned int checkOnes(int num)
{
    int count = 0;
    while(num > 0)
    {
        if(num % 2 == 1)
            count++;
            
        num = num >> 1;
    }
    return count;
}
unsigned int getNextSmallest_BruteForce(unsigned int num)
{
    int originalOnes = checkOnes(num);
    while(num >0)
    {
        if( originalOnes == checkOnes(++num))
            break;
    }
    return num;
}
unsigned int getNextLargest_BruteForce(unsigned int num)
{
    int originalOnes = checkOnes(num);
    while(num >0)
    {
        if( originalOnes == checkOnes(--num))
            break;
    }
    return num;
}
unsigned int getNextLargest(unsigned int num)
{
    //Find first 0
    int firstZero = 0;
    int count1 = 0;
    int count0 = 0;
    unsigned int tmp = num;
    while(tmp > 0)
    {
        
        if(tmp % 2 == 0)
        {
            count0++;
            break;
        }
        else
        {
            count1++;
            firstZero++;
            tmp = tmp >> 1;
        }
    }
    tmp = tmp >> 1;
    int oneNextFirstZero = firstZero+1;
    while(tmp > 0)
    {
        
        if(tmp % 2 == 1)
        {
            count1++;
            break;
        }
        else
        {
            count0++;
            oneNextFirstZero++;
            tmp = tmp >> 1;
        }
    }
    //Set 0s from 0~oneNextFirstZero
    num = (num >> (oneNextFirstZero+1))<<(oneNextFirstZero+1);
    count0--; //bit oneNextFirstZero has been set to 0;
    
    unsigned int allOnes = ~0;
    allOnes = ~(allOnes << count1);
    allOnes <<= count0;
    return num | allOnes;
}

unsigned int getNextSmallest(unsigned int num)
{
    //Find first 1
    int firstOne = 0;
    int count1 = 0;
    int count0 = 0;
    unsigned int tmp = num;
    while(tmp > 0)
    {
        
        if(tmp % 2 == 1)
        {
            count1++;
            break;
        }
        else
        {
            count0++;
            firstOne++;
            tmp = tmp >> 1;
        }
    }
    tmp = tmp >> 1;
    int zeroNextFirstOne = firstOne + 1;
    while(tmp > 0)
    {
        
        if(tmp % 2 == 0)
        {
            count0++;
            break;
        }
        else
        {
            zeroNextFirstOne++;
            count1++;
            tmp = tmp >> 1;
        }
    }
    if( (count1 + count0) == 32 || (count0+count1) == 0)
        return -1;
    //Set zeroNextFirstOne to 1
    num = (1<<zeroNextFirstOne) | num;

    num = (num >> (count0 + count1 -1 )) << (count0 + count1 -1);
    unsigned int mask;
    //One 1 has been set, thus count1-1
    mask = (1 << (count1-1)) -1;
    
    return num | mask;
}

 

Leave a Reply