LeetCode 9:回文数(Palindrome Number)解法汇总


更多LeetCode题解

我的解法/官方解法二

我的编程水平比较菜,所以只能想到这种最一般的解法啦。
即将数字逆序,并判断逆序后的数与原数是否相等。相等则为回文数。
这里给出我的C++代码。

class Solution {
public:
	bool isPalindrome(int x) {
		if (x >= 0)
		{
			queue<int> q;
			int temp = x;
			//push x into the queue
			while (x)
			{
				q.push(x % 10);
				x /= 10;
			}
			long long result = 0;
			//pop queue from the front
			while (!q.empty())
			{
				result *= 10;
				result += q.front();
				q.pop();
			}
			//judge if x is equal to reversed x
			if (temp == result)
			{
				return true;
			}
			else
				return false;
		}
		else
			return false;
	}
};

注意点

  1. 本题实际上是回文串的判断,对所有的负数都将负号也纳入判断之内,由于不可能存在某个复数的最后是负号,所以所有的负数都不是回文数。
  2. int类型的数在逆序后可能产生越界,需要一个long long类型来接收逆序后的数。

该方法的缺点

缺点就是上述的注意点的第二点啦。

官方解法三(目前我所见过的最优美的解法)

官方解法三其实是解法二的拓展,它只需要判断一半长度的x,因此避免了int类型的越界问题。
比如说1221这个数,如果我们能够将后面两位数21逆序为12,并将12与前两位数12比较,就可以得出它是回文数这个结论。

如何得知我们达到了一半长度的数呢?

我的第一想法是先计算x的位数,不就得到了一半是多长吗?哈哈,看完官方代码我才知道为啥我是菜鸡。
官方采用的做法是将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于反转后的数字时,就意味着我们已经处理了一半位数的数字。
下面给出官方的C#代码

public 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;
    }
}

如果看不懂C#的话那就看下面我写的C++版吧~

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

			return (x == reversedNumber || x == reversedNumber / 10);
		}
	}
};

其他解法

解法一

利用一个辅助的数据结构vector来进行判断,即将整数x的每一位通过取余的操作提取出来,存放到vector中,然后再进行判断。

class Solution {
public:
    bool isPalindrome(int x) {
        vector<int> v;
        if(x < 0)
            return false;
        while(x!=0)
        {
            v.push_back(abs(x%10));
            x = x/10;
        }
        int j = v.size()-1;
        for(int i=0;i<=j;i++,j--)
        {
            if(v[i] == v[j])
                continue;
            else
                return false;
        }
        return true;
    }
};

解法二

利用取整和取余来获得我们想要的数字,比如1221,如果计算 1221 / 1000, 则可得首位1, 如果 1221 % 10, 则可得到末尾1,进行比较,然后把中间的22取出来继续进行比较。

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

其实以上几种解法都大同小异啦。

转换为字符串处理

我们再来看看官方提出的第一种想法,将数字转换为一个字符串处理是不是简单多了?但是这种方法的效率并不高

java直接调用类方法

public boolean isPalindrome(int x) {
    if(x<9 && x>=0){
        return true;
    }
    String strI = Integer.toString(x);
    StringBuilder sbi = new StringBuilder(strI);
    String sbirev = sbi.reverse().toString();
    return sbirev.equals(strI);
}

C++

public bool IsPalindrome(int x) {
    string n = x.ToString();
    int max = n.Length -1;
    int min = 0;
    
    while(true)
    {
        if(min > max)
        {
            return true;
        }
        char a = n[min];
        char b = n[max];
        
        if(char.ToLower(a) != char.ToLower(b))
        {
            return false;
        }
        
        min++;
        max--;
    }
}

python(极致的简洁)

def isPalindrome(x):
	x = str(x)
	if x[::-1] == x:
	    return True
	return False
def isPalindrome(x):
	return x == int(str(x)[::-1]) and x > 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值