刷题日记——Day1

1.题目描述

        给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

•  例如,121 是回文数,而 123 不是。

2.解法1(个人角度)——逐位分割,折半对比

        看到题目之后,从数的角度考虑,回文数具有低位与高位相等的特点。

(1)建立一个整型数组,用来存储分割之后的数据

(2)进行逐位分割,存储在数组中

(3)折半对比,只需要比较一半的元素即可,判断是否为回文数

具体解法:

由题意知,负数必定不是回文数
0~9必定是回文数
其余的数,将其一一分解,放入数组中
这里采用了“投机取巧”的方法,int型的数据最多只有10位数,事先建立了一个能够包含10个元素数组
逐位分割之后,折中对比,首与尾相比,这里会出现一个易错点:如果两位数,下标则为1,除以2之后,则为0,就不会进行对比,对于此种情况,需进行判断,便可避免

代码实现:

bool isPalindrome(int x) 
{
	//情况1:负数 
    if(x < 0)
    {
        return false;
    }
    //情况2:个位数 
    else if((x >= 0) && (x < 10))
    {
        return true;
    }
    //情况3:大于9的整数 
    else
    {
        int i = 0,j = 0,k = 0,a[10] = {0};
        
        //进行逐位拆分 
        while(x / 10)
        {
            a[i] = x % 10;
            x /= 10;
            i++;
            if(x < 10) 
            {
            	a[i] = x;	
			}
        }
        
        j = i;
        k = j / 2;
        
        //两位数,则最大下标数为1,除以2后为0 
        if(0 == k)
        {
            k++;
        }
        
        //进行折半对比 
        for(i = 0;i <= k;i++)
        {
            if(a[i] != a[j-i])
            {
                return false;
            }
        }
    }
    return true;
}

3.解法2——反转一半数字比较

当然,题解中反转一半数字的方法也非常巧妙。
(1)负数和个位为0且不为0的数(因为最高位不可能为0),均不是回文数
(2)反转一半数字,利用取余每次得到最低位数字,每次除以10,将最低位舍弃
重点来了,那怎么判断是否数字已经反转了一半?
由于新数字在不断乘以10变大,原始数字不断除以10变小,当原始数字小于等于新数字时,说明就已经反转过半

说到这里,有的小伙伴可能在想,这样的算法可以站的住脚嘛?

比如,具有偶数位数的高位总比低位大,例如:654321
按照上述算法,原始数字:456,新数字:123,已经反转过半,但还是没有达到跳出循环的要求,最后一次循环,原始数字:65,新数字:1234
这里可能就会产生疑问,虽然上述示例不是回文数,返回值确实达到预期值,但是回文数可不可能出现错判呢?
事实并不会出现上述假设,对于回文数而言,偶数位数,反转一半后,其新数字与变换的原始数字必定相同;奇数位数,反转一半后,其新数字必定大于变换的原始数字

代码实现:

bool isPalindrome(int x)
{
	//负数和个位数为0且不为0的数,最高位数不可能为0 
	if((x < 0) || ((x > 0) && (x % 10 == 0))) 
	{
		return false;
	}
	
	//个位数 
	else if((x >= 0) && (x < 10))
	{
		return true;
	}
	
	//大于9且个位不为0的整数
	else
	{
		int temp = 0;
		while(x > temp)
		{
			temp = temp*10 + x %10;
			x /= 10;
		}
		if((x == temp) || (x == (temp /10)))
		{
			return true;
		}	
		else
		{
			return false;
		}
	} 
	
}

4.解法3——将数据转化为字符串,折半比较

此外,还可以采用转化字符串的方法,与本人解法类似,利用sprintf()函数,将整数转化为字符串,存储在字符数组中,用转化字符的方法代替逐位分割,后续步骤相同,进行折中对比,判断是否为回文数

int sprintf( char *buffer, const char *format [, argument] ... );

函数功能:把一个格式化的数据转化为字符串

第一个参数:指向写入字符串的数组,其他参数与printf( )函数相同

sprintf()函数,其更加具有实用性,具体还需在网上查阅相关资料

C代码代码实现:

bool isPalindrome(int x)
{
	char str[11] = {0};
	
	//将整型转化为字符串 
	sprintf(str,"%d",x);
	
	int len = strlen(str);
	
	int i = 0;
	for(i = 0;i <(len / 2);i++)
	{
		if(str[i] != str[len-1-i])
		{
			return false;
		}
		else
		{
			return true;
		}
	}
}

5.总结

        上述三种解法,本质都是将整数折半进行对比,但前面的过程略有不同,正所谓“各花各有各花香”,各自有各自的优势,其中实现的细节,值得大家去思考,去体会。

       部分解题思路参考力扣题解以及评论区中的大佬。 当然,如果这篇文章对你有所帮助或者有一种耳目一新的感觉,还请大家多支持支持,点点赞。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值