下一個數。給定一個正整數,找出與其二進制表達式中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;
}
};