力扣OJ 面試題 05.04. 下一個數

下一個數。給定一個正整數,找出與其二進制表達式中1的個數相同且大小最接近的那兩個數(一個略大,一個略小)。

示例1:

 輸入:num = 2(或者0b10)
 輸出:[4, 1] 或者([0b100, 0b1])
示例2:

 輸入:num = 1
 輸出:[2, -1]
提示:

num的範圍在[1, 2147483647]之間;
如果找不到前一個或者後一個滿足條件的正數,那麼輸出 -1。

 

 

itoa和atoi都是直接百度複製的,nextGreaterElement函數是從我另外一個題目代碼複製過來略改的

https://blog.csdn.net/nameofcsdn/article/details/106915634

只需要改2個地方,一個是整數轉化爲二進制字符串,一個是二進制字符串轉化爲整數。

nextLesserElement函數是nextGreaterElement函數直接修改得到,代碼邏輯是一樣的。

char* itoa(int num,char* str,int radix)  //copy from 百度百科
{/*索引表*/
    char index[]="0123456789ABCDEF";
    unsigned unum;/*中間變量*/
    int i=0,j,k;
    /*確定unum的值*/
    if(radix==10&&num<0)/*十進制負數*/
    {
        unum=(unsigned)-num;
        str[i++]='-';
    }
    else unum=(unsigned)num;/*其他情況*/
    /*轉換*/
    do{
        str[i++]=index[unum%(unsigned)radix];
        unum/=radix;
       }while(unum);
    str[i]='\0';
    /*逆序*/
    if(str[0]=='-')
        k=1;/*十進制負數*/
    else
        k=0;
     
    for(j=k;j<=(i-1)/2;j++)
    {       char temp;
        temp=str[j];
        str[j]=str[i-1+k-j];
        str[i-1+k-j]=temp;
    }
    return str;
}
int atoi2(const char *nptr)
{
        int c;              /* current char */
        int total;         /* current total */
        int sign;           /* if '-', then negative, otherwise positive */

        /* skip whitespace */
        while ( isspace((int)(unsigned char)*nptr) )
            ++nptr;

        c = (int)(unsigned char)*nptr++;
        sign = c;           /* save sign indication */
        if (c == '-' || c == '+')
            c = (int)(unsigned char)*nptr++;    /* skip sign */

        total = 0;

        while (isdigit(c)) {
            total = 2 * total + (c - '0');     /* accumulate digit */
            c = (int)(unsigned char)*nptr++;    /* get next char */
        }

        if (sign == '-')
            return -total;
        else
            return total;   /* return result, negated if necessary */
}
int nextGreaterElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        int len=strlen(sn);
        for(int i=len-2;i>=0;i--)
        {
            if(sn[i]>=sn[i+1])continue;
            for(int j=len-1;j>i;j--)
            {
                if(sn[i]>=sn[j])continue;                
                sn[j]^=sn[i]^=sn[j]^=sn[i];
                sort(sn+i+1,sn+len);
                long long res = atoi2(sn);
                if(res==int(res))return res;
                return -1;
            }
        }
        return -1;
    }
int nextLesserElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        int len=strlen(sn);
        for(int i=len-2;i>=0;i--)
        {
            if(sn[i]<=sn[i+1])continue;
            for(int j=len-1;j>i;j--)
            {
                if(sn[i]<=sn[j])continue;                
                sn[j]^=sn[i]^=sn[j]^=sn[i];
                sort(sn+i+1,sn+len,greater<char>());
                long long res = atoi2(sn);
                if(res==int(res))return res;
                return -1;
            }
        }
        return -1;
    }
class Solution {
public:
    vector<int> findClosedNumbers(int num) {
        vector<int> ans(2);
        ans[1]=nextLesserElement(num);
        ans[0]=nextGreaterElement(num);
        return ans;
    }
};

 

後來發現可以用c++的庫函數獲取上一個下一個全排列,就更簡單了

//把整數轉化爲字符串
char* itoa(int num,char* str,int radix)  //copy from 百度百科
{/*索引表*/
    char index[]="0123456789ABCDEF";
    unsigned unum;/*中間變量*/
    int i=0,j,k;
    /*確定unum的值*/
    if(radix==10&&num<0)/*十進制負數*/
    {
        unum=(unsigned)-num;
        str[i++]='-';
    }
    else unum=(unsigned)num;/*其他情況*/
    /*轉換*/
    do{
        str[i++]=index[unum%(unsigned)radix];
        unum/=radix;
       }while(unum);
    str[i]='\0';
    /*逆序*/
    if(str[0]=='-') k=1;/*十進制負數*/
    else k=0;     
    for(j=k;j<=(i-1)/2;j++)
    {   
        char temp;
        temp=str[j];
        str[j]=str[i-1+k-j];
        str[i-1+k-j]=temp;
    }
    return str;
}
//把字符串轉化爲整數
long long atoi(const char *nptr,int radix) //copy from somebody
{        
        while ( isspace((int)(unsigned char)*nptr) )  ++nptr;/* skip whitespace */
        int c = (int)(unsigned char)*nptr++;
        int sign = c;           /* save sign indication */
        if (c == '-' || c == '+')  c = (int)(unsigned char)*nptr++;    /* skip sign */
        long long total = 0;
        while (isdigit(c)) {
            total = radix * total + (c - '0');     /* accumulate digit */
            c = (int)(unsigned char)*nptr++;    /* get next char */
        }
        if (sign == '-')   return -total;
        else  return total;   /* return result, negated if necessary */
}
int nextGreaterElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        next_permutation(sn,sn+32);        
        long long res = atoi(sn,2);
        if(res==int(res))return res;
        return -1;
}
int nextLesserElement(int n) {
        char sn[40];
        for(int i=0;i<32;i++)sn[i]=((n&(1<<31-i))?'1':'0');
        sn[32]='\0';
        prev_permutation(sn,sn+32);        
        long long res = atoi(sn,2);
        if(res==int(res))return res;
        return -1;
}
class Solution {
public:
    vector<int> findClosedNumbers(int num) {
        vector<int> ans(2);
        ans[1]=nextLesserElement(num);
        ans[0]=nextGreaterElement(num);
        return ans;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章