9.回文数

  1. 9.回文数
    1. 9.1 题目
    2. 9.2 题解
      1. 转字符串头尾指针比较
      2. 翻转数字后比较
      3. 翻转字符串后遍历比较
    3. 9.3 代码
    4. 9.4 运行结果

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

×

喜欢就点赞,疼爱就打赏