LeetCode 9. 回文数(反转一半的数字)

2021年04月14日 周三 天气晴 【不悲叹过去,不荒废现在,不惧怕未来】


1. 题目简介

9. 回文数
在这里插入图片描述

2. 题解

2.1 计算首尾数值进行比较

刚开始的思路是,先计算位数,然后根据位数计算首尾数值,进行比较。

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0) return false;
        int tmp = x, n = 0;
        while(tmp){
            tmp /= 10;
            ++n;
        }
        int a = x, b = x, cnt = n;
        int beg = 0, end = 0;
        for(int i=0;i<n/2;++i){
            beg = a / pow(10,cnt-1);
            end = b % 10;
            if(beg!=end){
                return false;
            }
            a -= beg * pow(10,cnt-1);
            b /= 10;
            --cnt;
        }
        return true;
    }
};

乍一看,我还以为这种方法和官方题解一样,也是 O(logn) 的时间复杂度,毕竟提交也通过了。但是后来我转念一想,第二个循环中用到了 pow 函数,就算 pow 的时间复杂度当作 O(logn) ,总的时间复杂度也是 O(log(n!)) 。之所以提交通过了,可能是编译器对 自带的 pow 函数进行优化了吧(pow 函数的源码十分复杂,具体的时间复杂度是多少我也没有深究)。

2.2 反转一半的数字(掌握)

官方题解是真正的 O(logn) ,思路比较巧妙:在计算后部分数字的同时,不断缩小前部分数字,直到前部分数字小于等于后部分数字,然后根据前部分数字和后部分数字的大小是否相等判断最终结果(奇数特殊考虑)。

class Solution {
public:
    bool isPalindrome(int x) {
        // 特殊情况:
        // 如上所述,当 x < 0 时,x 不是回文数。
        // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
        // 则其第一位数字也应该是 0
        // 只有 0 满足这一属性
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        while (x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
        // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
        // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x == revertedNumber || x == revertedNumber / 10;
    }
};

在这里插入图片描述


参考文献

https://leetcode-cn.com/problems/palindrome-number/solution/hui-wen-shu-by-leetcode-solution/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值