Leetcode --9

来源:互联网 发布:炉石淘宝买卡背 编辑:程序博客网 时间:2024/06/06 03:57

原题链接:https://leetcode.com/problems/palindrome-number/#/description

题目:Determine whether an integer is a palindrome. Do this without extra space.

Some hints:

Could negative integers be palindromes? (ie, -1)

If you are thinking of converting the integer to string, note the restriction of using extra space.

You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case?

There is a more generic way of solving this problem.

题目理解:

首先清楚palindrome是什么,指的是一个数正向、反向读为同一个数,例如:121、2332、9、0、24442等。从第一条提示中可以看出,负数并不是palindrome,所以所有负数都将返回false。



class Solution {public:    bool isPalindrome(int x) {                bool result=false;                if(x<0||(x!=0 && x%10==0)){            return result;        }        int sum=0;        while(x>sum){                        sum=sum*10+x%10;            x=x/10;                    }                if(sum==x||x==sum/10){            result=true;        }       return result;       }};

首先,负数、以及十的整数倍的数字肯定不是palindrome,返回false,下面while循环体是将x反转一半,例如将124421,经过while循环后,sum将得到124;强123经过while循环后将得到32。这么做的目的就是比较x前半部分以及x后半部分的反转sum。

最后的if语句是判断x是否为回文数。若sum==x,则肯定是回文数(如x=12344321);后面x==sum/10时是为了处理x位数为奇数位时发生的情况,如x=121或x=12321这种情况。


补充知识点:

1.c++可以定义10进制、8进制、16进制的数:

int a=0x80000000

a位16进制的int型。


2.有符号和无符号数的左移和右移

先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如:
int i = 1;
i = i << 2; //把i里的值左移2位
也就是说,1的2进制是000...0001(这里1前面0的个数和int的位数有关,32位机器,gcc里有31个0),左移2位之后变成000... 0100,也就是10进制的4,所以说左移1位相当于乘以2,那么左移n位就是乘以2的n次方了(有符号数不完全适用,因为左移有可能导致符号变化,下面 解释原因)
需要注意的一个问题是int类型最左端的符号位和移位移出去的情况.我们知道,int是有符号的整形数,最左端的1位是符号位,即0正1负,那么移位的时候就会出现溢出,例如:
int i = 0x40000000; //16进制的40000000,为2进制的01000000...0000
i = i << 1; 
那么,i在左移1位之后就会变成0x80000000,也就是2进制的100000...0000,符号位被置1,其他位全是0,变成了int类型所能表 示的最小值,32位的int这个值是-2147483648,溢出.如果再接着把i左移1位会出现什么情况呢?在C语言中采用了丢弃最高位的处理方法,丢 弃了1之后,i的值变成了0.
左移里一个比较特殊的情况是当左移的位数超过该数值类型的最大位数时,编译器会用左移的位数去模类型的最大位数,然后按余数进行移位,如:
int i = 1, j = 0x80000000; //设int为32位
i = i << 33; // 33 % 32 = 1 左移1位,i变成2
j = j << 33; // 33 % 32 = 1 左移1位,j变成0,最高位被丢弃
在用gcc编译这段程序的时候编译器会给出一个warning,说左移位数>=类型长度.那么实际上i,j移动的就是1位,也就是33%32后的余数.在gcc下是这个规则,别的编译器是不是都一样现在还不清楚.
总之左移就是: 丢弃最高位,0补最低位
再说右移,明白了左移的道理,那么右移就比较好理解了.
右移的概念和左移相反,就是往右边挪动若干位,运算符是>>.
右移对符号位的处理和左移不同,对于有符号整数来说,比如int类型,右移会保持符号位不变,例如:
int i = 0x80000000;
i = i >> 1; //i的值不会变成0x40000000,而会变成0xc0000000
就是说,符号位向右移动后,正数的话补0,负数补1,也就是汇编语言中的算术右移.同样当移动的位数超过类型的长度时,会取余数,然后移动余数个位.
总之,在C中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变.实际应用中可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多.








0 0
原创粉丝点击