leetcode - 9 回文数 解法探讨

题目:

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

解法及思路:

//分析:
//由示例可知:负数和末尾为0(除0外)的数都不是回文数
//那么需要判断正数中,左侧的数是否等于右边

bool isPalindrome(int x){
    
    int len;
    int temp = x;
    
    if( x<0 || ((x%10 == 0) && (x!=0)) )
        return false;
    
    else if(x == 0)
        return true;
    
    else{
        //求x的长度len
        for(len = 0; temp>0; len++){
            temp = temp/10;
        }
        //printf("len = %d\n",len);//确认长度计算正确
        //把x放进数组里
        int* n = (int*) malloc(sizeof(int)*len);
        temp = x;
        for(int i=len-1; i>=0; i--){
            n[i] = temp%10;
            temp = temp/10;           
        }
        //打印数组,确认数组正确
        //for(int a=0;a<len;a++){
        //    printf("%d",n[a]);
        //}        
        //printf("\n");
        
        //对比
        //此处发现代码的重大问题!如果在for中使用continue,虽然不进循环,但是i++和j--仍会执行
        int i = 0, j = len-1;
        //注意:j是大于等于!!
        while(i<len && j>=0){
            if(n[i] != n[j]){
                return false;
                break;
            }
            else if(n[i] == n[j]){
                if(i == len/2){
                    return true;
                    break;
                }
            }
                i++;
                j--;

        }
    }             
    return 0;
}

反思:

在写代码的时候遇到几个问题:

1.做题喜欢按照数学想法,分情况讨论,并且总按第一直接去解题。本来以为只要能解答正确都算过关,但实际上不能这样,在很多现实情况下,需要最优解法,以节省资源。对工作尤其重要,所以后面要继续学习算法。首先要搞清楚时间复杂度的概念

2.做回文数的题时,第一想法是把数拆分开放进数组里,再去比较数组里前后时候相等。所以首先要获得x的数字长度,再放进数组(因为要给数组确定长度大小,再定义)。

确认数字长度的方法是:用x/10,用len计数,确认x有几位。

然后申请len位的数组大小,把x拆分开放进去:x%10获得末位,再将x/10舍去末位。

3.在写代码时,我刚开始用到了for循环来判断数组中的数:for(i=0,j=len-1;i<len&&j>=0;i++,j--),虽然返回结果是对的,但i和j的数值却和我的预期不一致。后来调试时发现,是因为我在循环中用到了continue。当时我想达成的结果是:在两侧值相等的情况下,就判断i是否已经到了中间,如果到了中间,就证明两侧的数都相同,返回true;否则下标就继续递增/递减。

结果输出结果是对了,但是i和j都一直加到了最边缘的值,并非是我预期的中间值。经查资料,如果在for中使用continue,虽然跳过了后面的语句,但是i++和j--仍会执行。

实际上不需要用continue,让程序顺序执行即可。

同时for里的循环条件,是大范围,不影响计算量(因为for里还有判断条件),同时还可规避一些极端条件,比如len=1时,计算很容易越界。

4.在数组中,用循环判断首位和末位是否相同,如果相同,再往中间靠拢,直到到达中间位。

对于奇数而言,中间位仅一位,可以不用考虑,所以下标判断到len/2即可;

对于偶数而言,中间位有二位,下标判断到len/2-1。

但其实这样区分,只会影响计算量,并不会对输出结果造成影响,所以可以都判断到len/2,无须对代码进行奇数偶数的区分。

5.在写代码时,建议用printf判断变量的值是否符合预期,方便debug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值