力扣题解之9. Palindrome Number 回文数:深入剖析与拓展
在算法学习的旅程中,判断一个数是否为回文数是一个经典且基础的问题。本题不仅考验对基本编程逻辑的掌握,还能拓展对不同数据处理方式的理解。本文将对 “Palindrome Number” 这一问题进行全面解析,涵盖多种语言实现、算法分析,并对题目进行扩充以增加难度。
一、题目详情
题目地址:https://leetcode.com/problems/palindrome-number/#/description
题目描述
判断一个整数是否为回文数。当一个整数从左到右和从右到左读都一样时,它就是一个回文数。
示例说明
- 示例 1:
- 输入:121
- 输出:true
- 示例 2:
- 输入:-121
- 输出:false
- 解释:从左到右,它读作 -121。从右到左,它变为 121 -。因此它不是一个回文数。
- 示例 3:
- 输入:10
- 输出:false
- 解释:从右到左读作 01。因此它不是一个回文数。
进阶要求
能否在不将整数转换为字符串的情况下解决此问题?
二、解题方法与代码实现
(一)转换为字符串法
思路阐述
- 首先判断整数是否为负数,如果是负数则直接返回
False,因为负数不可能是回文数(符号的存在破坏了回文特性)。 - 将整数转换为字符串,方便对其字符进行逐个比较。
- 获取字符串的长度,通过遍历字符串的前半部分,与后半部分对应位置的字符进行比较。如果存在任何一对字符不相等,则返回
False。 - 如果遍历完前半部分都没有发现不相等的字符,则返回
True。
Python 代码实现
class Solution:
def isPalindrome(self, x):
if x < 0:
return False
x = str(x)
N = len(x)
for i in range(N // 2):
if x[i] != x[N - 1 - i]:
return False
return True
Java 代码实现
class Solution {
public boolean isPalindrome(int x) {
if (x < 0) {
return false;
}
String str = String.valueOf(x);
int N = str.length();
for (int i = 0; i < N / 2; i++) {
if (str.charAt(i) != str.charAt(N - 1 - i)) {
return false;
}
}
return true;
}
}
C 代码实现
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
char str[20];
sprintf(str, "%d", x);
int N = strlen(str);
for (int i = 0; i < N / 2; i++) {
if (str[i] != str[N - 1 - i]) {
return false;
}
}
return true;
}
C++ 代码实现
#include <iostream>
#include <string>
using namespace std;
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
string str = to_string(x);
int N = str.length();
for (int i = 0; i < N / 2; i++) {
if (str[i] != str[N - 1 - i]) {
return false;
}
}
return true;
}
};
Go 代码实现
package main
import (
"fmt"
"strconv"
)
func isPalindrome(x int) bool {
if x < 0 {
return false
}
str := strconv.Itoa(x)
N := len(str)
for i := 0; i < N/2; i++ {
if str[i] != str[N-1-i] {
return false
}
}
return true
}
(二)翻转数字法
思路阐述
- 同样先判断整数是否为负数,若是则返回
False。 - 保存原始整数
x到另一个变量y,用于后续比较。 - 通过循环,不断取出
y的最后一位数字,添加到res中,实现数字的翻转。具体做法是:每次将res乘以 10,再加上y除以 10 的余数(即y的最后一位数字),然后将y除以 10 去掉最后一位。 - 循环结束后,比较
x和翻转后的res。如果相等,则x是回文数,返回True;否则返回False。
Python 代码实现
class Solution:
def isPalindrome(self, x):
if x < 0:
return False
y = x
res = 0
while y > 0:
res = res * 10 + y % 10
y //= 10
return x == res
Java 代码实现
class Solution {
public boolean isPalindrome(int x) {
if (x < 0) {
return false;
}
int y = x;
int res = 0;
while (y > 0) {
res = res * 10 + y % 10;
y /= 10;
}
return x == res;
}
}
C 代码实现
#include <stdbool.h>
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
int y = x;
int res = 0;
while (y > 0) {
res = res * 10 + y % 10;
y /= 10;
}
return x == res;
}
C++ 代码实现
#include <iostream>
using namespace std;
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
int y = x;
int res = 0;
while (y > 0) {
res = res * 10 + y % 10;
y /= 10;
}
return x == res;
}
};
Go 代码实现
package main
import "fmt"
func isPalindrome(x int) bool {
if x < 0 {
return false
}
y := x
res := 0
for y > 0 {
res = res*10 + y%10
y /= 10
}
return x == res
}
三、算法分析
时间复杂度
- 转换为字符串法:将整数转换为字符串的操作时间复杂度取决于整数的位数,通常为 (O(\log_{10}n)),其中 (n) 是整数的绝对值。遍历字符串进行比较的时间复杂度也是 (O(\log_{10}n)),所以总体时间复杂度为 (O(\log_{10}n))。
- 翻转数字法:循环的次数取决于整数的位数,每次循环执行固定次数的操作,所以时间复杂度同样为 (O(\log_{10}n))。
空间复杂度
- 转换为字符串法:需要额外的空间来存储转换后的字符串,空间复杂度为 (O(\log_{10}n))。
- 翻转数字法:除了几个常数级别的变量(如
y和res)外,没有使用额外的与输入规模相关的空间,所以空间复杂度为 (O(1))。从空间利用效率上看,翻转数字法更优。
四、题目扩充与拓展
扩充题目
判断一个整数在特定进制下是否为回文数,实现函数 isPalindromeInBase(x, base),其中 x 是要判断的整数,base 是进制(2 <= base <= 16)。
解题思路
- 负数处理:与原问题类似,负数在任何进制下都不是回文数,直接返回
False。 - 转换为指定进制字符串:将整数
x转换为指定进制base的字符串表示。可以通过不断对base取余并记录余数来实现,余数范围在 0 到base - 1之间。对于大于 9 的余数,用字母(如A表示 10,B表示 11 等)表示。 - 判断回文:类似于原问题转换为字符串法,遍历字符串的前半部分,与后半部分对应位置的字符进行比较,判断是否为回文。
代码实现(以 Python 为例)
def isPalindromeInBase(x, base):
if x < 0:
return False
if base < 2 or base > 16:
return False
digits = "0123456789ABCDEF"
num_str = ""
while x > 0:
num_str = digits[x % base] + num_str
x //= base
N = len(num_str)
for i in range(N // 2):
if num_str[i] != num_str[N - 1 - i]:
return False
return True
复杂度分析
- 时间复杂度:将整数转换为指定进制字符串的操作时间复杂度取决于整数在该进制下的位数,通常为 (O(\log_{base}n)),其中 (n) 是整数的绝对值。遍历字符串进行比较的时间复杂度也是 (O(\log_{base}n)),所以总体时间复杂度为 (O(\log_{base}n))。
- 空间复杂度:需要额外的空间来存储转换后的字符串,空间复杂度为 (O(\log_{base}n))。
通过对 “Palindrome Number” 问题的详细解析、多种语言实现以及题目扩充,希望读者能更深入理解回文数判断问题,并提升解决相关算法问题的能力。在实际编程中,可根据具体场景选择合适的方法,并能灵活应对类似问题的变体。

2798

被折叠的 条评论
为什么被折叠?



