「LeetCode」9.回文数

407 阅读2分钟

题目描述🌍

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

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

示例 1

输入:x = 121
输出:true

示例 2

输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

示例 3

输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。

示例 4

输入:x = -101
输出:false

提示

  • 231x2311-2^{31} \leq x \leq 2^{31} - 1

进阶:你能不将整数转为字符串来解决这个问题吗?

双指针🔎

解题思路

首先将整数 int 转换为字符串 String 再转换成字符数组 char[],然后再将两个指针分别指向 char[] 的首部与尾部,判断相等后同时向中间逐一移动;大多数人都能想到这种解法。

代码

Java

class Solution {
    public boolean isPalindrome(int x) {
        String number = Integer.toString(x);
        char[] chars = number.toCharArray();
        for (int i = 0; i <= (chars.length - 1) / 2; i++) {
            if (chars[i] != chars[chars.length - i - 1]) {
                return false;
            }
        }
        return true;
    }
}

C++

class Solution {
public:
    bool isPalindrome(int x) {
        string str = to_string(x);
        int length = str.length();
        for (int i = 0; i < length / 2; i++) {
            if (str.at(i) != str.at(length - i - 1)) {
                return false;
            }
        }
        return true;
    }
};

时间复杂度:O(n)O(n)

空间复杂度:O(1)O(1)

数学方法(进阶)🌲

解题思路

通过不断获取整数中(第一个数字)与(最后一个数字)进行比较,然后剔除头尾数字后重复上述操作,直至头尾不相等(false)或整数比较完毕(true)。

该方法本身不难,但我们不妨思考下为什么如下程序段可以有效地排除例如 100221、100021 这类数字。

// 试着在脑海中运行下对于这类数字该段程序的运行轨迹 / Debug
while (x > 0) {
    if ((x / divide) != (x % 10))
    	return false;
    x = (x % divide) / 10;
    divide /= 100;
}

代码

Java

class Solution {
    public boolean isPalindrome(int x) {
        if (x < 0)
            return false;
        int divide = 1;
        while (x / divide >= 10)
            divide *= 10;
        while (x > 0) {
            if ((x / divide) != (x % 10))
                return false;
            x = (x % divide) / 10;
            divide /= 100;
        }
        return true;
    }
}

C++

class Solution {
public:
    bool isPalindrome(int x) {
        if (x < 0)
            return false;
        int divide = 1;
        while (x / divide >= 10)
            divide *= 10;
        while (x != 0) {
            if (x / divide != x % 10)
                return false;
            x = (x % divide) / 10;
            divide /= 100;
        }
        return true;
    }
};

时间复杂度:O(n)O(n)

空间复杂度:O(1)O(1)

折半反转判别法(进阶)⚡

解题思路

图解来源于 LeetCode 官网

代码

Java

class Solution {
    public boolean isPalindrome(int x) {
        // 避免 x 为 10 的倍数, 该情况不符合如下解法
        if (x < 0 || x % 10 == 0 && x != 0)
            return false;
        int halfReverse = 0;
        while (x > halfReverse) {
            halfReverse = halfReverse * 10 + x % 10;
            x /= 10;
        }
        return x == halfReverse || x == halfReverse / 10;
    }
}

C++

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

时间复杂度:O(n)O(n)

空间复杂度:O(1)O(1)

知识点🌓

双指针:指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。

LeetCode 中还有很多题目可以通过双指针解决,包括但不限于:www.jianshu.com/p/2fab49be0…

最后🌅

该篇文章为 「LeetCode」 系列的 No.4 篇,在这个系列文章中:

  • 尽量给出多种解题思路
  • 提供题解的多语言代码实现
  • 记录该题涉及的知识点

👨‍💻争取做到 LeetCode 每日 1 题,所有的题解/代码均收录于 「LeetCode」 仓库,欢迎随时加入我们的刷题小分队!