9.回文数
9.1 题目
给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例:
示例 1:
- 输入:
x = 121
- 输出:
true
- 输入:
示例 2:
- 输入:
x = -121
- 输出:
false
- 解释:从左向右读为
-121
,从右向左读为121-
。因此它不是一个回文数。
- 输入:
示例 3:
- 输入:
x = 10
- 输出:
false
- 解释:从右向左读为
01
。因此它不是一个回文数。
- 输入:
提示:
-2^31 <= x <= 2^31 - 1
进阶:你能不将整数转为字符串来解决这个问题吗?
9.2 题解
转字符串头尾指针比较
// 方法一:转字符串头尾指针比较
static bool IsPalindrome1(int x)
{
// 将整数转换为字符串
string xString = x.ToString();
// 初始化循环变量 i,从字符串的开头向中间遍历
int i = 0;
// 使用循环判断是否为回文数
while (i < xString.Length / 2)
{
// 检查对称位置的字符是否相等,不相等则不是回文数
if (xString[i] != xString[xString.Length - 1 - i])
{
return false;
}
// 移动到下一个字符位置
i++;
}
// 如果循环结束,说明整数是回文数
return true;
}
翻转数字后比较
// 方法二:翻转数字后比较
// 翻转原理
// 1.对于x,取出个位,取后抛弃个位
// 第一次:123321 % 10 = 1,123321 / 10 = 12332
// 第二次:12332 % 10 = 2, 12332 / 10 = 1233
// 第三次:1233 % 10 = 3, 1233 / 10 = 123
// 第四次:123 % 10 = 3, 123 / 10 = 12
// 第五次:12 % 10 = 2, 12 / 10 = 1
// 第六次:1 % 10 = 1, 1 / 10 = 0
// 通过这几次计算,当最后得到0时就可以停止了,证明我们已经从个位开始把每一位都单独提取了出来,那么我们只需要将其组合成一个新的数就可以和原数比较了
// 2.用一个数记录取出的数,每次记录时成10将个位空出来,加上取出的个位
// 第一次:revertedNumber * 10 + 1 = 1
// 第二次:revertedNumber * 10 + 2 = 12
// 第三次:revertedNumber * 10 + 3 = 123
// 第四次:revertedNumber * 10 + 3 = 1233
// 第五次:revertedNumber * 10 + 2 = 12332
// 第六次:revertedNumber * 10 + 1 = 123321
// 3.用得到的倒序数字和原数字比较即可
//4. 可以进行优化处理
//x < 0或x最后一位是0且x不是0 先排除
//使用以上翻转原理逐步翻转直到revertedNumber大于x后,比较x是否和翻转数相等,比如123 = 123
//假如当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
//比较x == revertedNumber / 10即可
static bool IsPalindrome2(int x)
{
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
if (x < 0 || (x % 10 == 0 && x != 0))
{
return false;
}
// 初始化一个变量用于存储反转后的数字
int revertedNumber = 0;
// 当输入的数字大于反转后的数字时,继续进行反转
while (x > revertedNumber)
{
// 将反转后的数字乘以10,然后加上输入数字的个位数
revertedNumber = revertedNumber * 10 + x % 10;
// 去掉输入数字的个位数
x /= 10;
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x == revertedNumber || x == revertedNumber / 10;
}
翻转字符串后遍历比较
// 方法三:翻转字符串后遍历比较
static bool IsPalindrome3(int x)
{
// 将整数转换为字符串
string xString = x.ToString();
// 将字符串转换为字符数组,并反转字符数组
char[] chars = xString.ToCharArray();
Array.Reverse(chars);
string reverseXString = new string(chars);
// 检查原始字符串和反转字符串是否一致
for (int i = 0; i < xString.Length; i++)
{
// 如果原始字符串和反转字符串的对应位置的字符不相等,则不是回文数
if (xString[i] != reverseXString[i])
{
return false;
}
}
// 如果所有对应位置的字符都相等,则是回文数
return true;
}
9.3 代码
using System;
class Program
{
static void Main()
{
#region 题目
// 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
// 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
// 示例 1:
// 输入:x = 121
// 输出:true
// 示例 2:
// 输入:x = -121
// 输出:false
// 解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
// 示例 3:
// 输入:x = 10
// 输出:false
// 解释:从右向左读, 为 01 。因此它不是一个回文数。
// 提示:
// -231 <= x <= 231 - 1
// 进阶:你能不将整数转为字符串来解决这个问题吗?
#endregion
#region 测试
// 示例 1
int x1 = 121;
bool result11 = IsPalindrome1(x1);
Console.WriteLine($"示例1 方法1 输出:{result11}");
bool result12 = IsPalindrome2(x1);
Console.WriteLine($"示例1 方法2 输出:{result12}");
// 示例 2
int x2 = -121;
bool result21 = IsPalindrome1(x2);
Console.WriteLine($"示例2 方法1 输出:{result21}");
bool result22 = IsPalindrome2(x2);
Console.WriteLine($"示例2 方法2 输出:{result22}");
// 示例 3
int x3 = 10;
bool result31 = IsPalindrome1(x3);
Console.WriteLine($"示例3 方法1 输出:{result31}");
bool result32 = IsPalindrome2(x3);
Console.WriteLine($"示例3 方法2 输出:{result32}");
#endregion
}
#region 答案
// 方法一:转字符串头尾指针比较
static bool IsPalindrome1(int x)
{
// 将整数转换为字符串
string xString = x.ToString();
// 初始化循环变量 i,从字符串的开头向中间遍历
int i = 0;
// 使用循环判断是否为回文数
while (i < xString.Length / 2)
{
// 检查对称位置的字符是否相等,不相等则不是回文数
if (xString[i] != xString[xString.Length - 1 - i])
{
return false;
}
// 移动到下一个字符位置
i++;
}
// 如果循环结束,说明整数是回文数
return true;
}
// 方法二:翻转数字后比较
// 翻转原理
// 1.对于x,取出个位,取后抛弃个位
// 第一次:123321 % 10 = 1,123321 / 10 = 12332
// 第二次:12332 % 10 = 2, 12332 / 10 = 1233
// 第三次:1233 % 10 = 3, 1233 / 10 = 123
// 第四次:123 % 10 = 3, 123 / 10 = 12
// 第五次:12 % 10 = 2, 12 / 10 = 1
// 第六次:1 % 10 = 1, 1 / 10 = 0
// 通过这几次计算,当最后得到0时就可以停止了,证明我们已经从个位开始把每一位都单独提取了出来,那么我们只需要将其组合成一个新的数就可以和原数比较了
// 2.用一个数记录取出的数,每次记录时成10将个位空出来,加上取出的个位
// 第一次:revertedNumber * 10 + 1 = 1
// 第二次:revertedNumber * 10 + 2 = 12
// 第三次:revertedNumber * 10 + 3 = 123
// 第四次:revertedNumber * 10 + 3 = 1233
// 第五次:revertedNumber * 10 + 2 = 12332
// 第六次:revertedNumber * 10 + 1 = 123321
// 3.用得到的倒序数字和原数字比较即可
//4. 可以进行优化处理
//x < 0或x最后一位是0且x不是0 先排除
//使用以上翻转原理逐步翻转直到revertedNumber大于x后,比较x是否和翻转数相等,比如123 = 123
//假如当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
//比较x == revertedNumber / 10即可
static bool IsPalindrome2(int x)
{
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
if (x < 0 || (x % 10 == 0 && x != 0))
{
return false;
}
// 初始化一个变量用于存储反转后的数字
int revertedNumber = 0;
// 当输入的数字大于反转后的数字时,继续进行反转
while (x > revertedNumber)
{
// 将反转后的数字乘以10,然后加上输入数字的个位数
revertedNumber = revertedNumber * 10 + x % 10;
// 去掉输入数字的个位数
x /= 10;
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x == revertedNumber || x == revertedNumber / 10;
}
// 方法三:翻转字符串后遍历比较
static bool IsPalindrome3(int x)
{
// 将整数转换为字符串
string xString = x.ToString();
// 将字符串转换为字符数组,并反转字符数组
char[] chars = xString.ToCharArray();
Array.Reverse(chars);
string reverseXString = new string(chars);
// 检查原始字符串和反转字符串是否一致
for (int i = 0; i < xString.Length; i++)
{
// 如果原始字符串和反转字符串的对应位置的字符不相等,则不是回文数
if (xString[i] != reverseXString[i])
{
return false;
}
}
// 如果所有对应位置的字符都相等,则是回文数
return true;
}
#endregion
}
9.4 运行结果
示例1 方法1 输出:True
示例1 方法2 输出:True
示例2 方法1 输出:False
示例2 方法2 输出:False
示例3 方法1 输出:False
示例3 方法2 输出:False
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com