Leetcode解题笔记:题7~9

7.整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

第七题以及后面的第八题都涉及一个核心问题:字符串转数字的溢出判断。反转数字的算法很简单,关键是在反转的同时防止溢出。
这个问题我在另一篇博客里写过:防止溢出
需要注意的是对于正数和负数的处理略有不同,因为 INT_MIN 和 INT_MAX 的绝对值并不是相等的,INT_MIN的绝对值大1。

int reverse(int x) {
		int ans = 0;
		int temp = 0;
		int r = 0;
		if (x >= 0)
			while (x) {
				r = x % 10;
				if (INT_MAX / 10 < temp) return 0;
				temp = ans * 10;
				if (INT_MAX - r < temp) return 0;
				ans = temp + r;
				temp = ans;
				x /= 10;
			}
		else 
			while (x) {
					r = x % 10;
					if (INT_MIN / 10 > temp) return 0;
					temp = ans * 10;
					if (INT_MIN - r > temp) return 0;
					ans = temp + r;
					x /= 10;
					temp = ans;	
		}
		return ans;
	}

8.字符串转换整数 (atoi)

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,qing返回 INT_MAX (231 − 1) 或 INT_MIN (−231)

这一题题目描述很长,其实就是两个核心:

  • 有效字符串部分的截取

  • 字符串转数字过程的溢出判断

    当然,说得简单就两个核心,真的实现起来可能忽略很多细节,反正我是尝试了很多次才通过了提交。。。举一个例子:
    字符串转数字的时候注意 ASCII 值不是直接运算的,否则以为算的是 ‘1’,结果是‘49’(1的ASCII值),输进去一个1111输出5万多,错误可能就是源于这个

int myAtoi(string str) {
        if(str.size()==0)return 0;
        int head=0;
        while(head<str.size()){
        	if(str[head]==' ')head++;
        	else break;
		}
		if(str[head]!='+'&&str[head]!='-'&&(str[head]>'9'||str[head]<'0'))return 0;
		else if((str[head]>='0'&&str[head]<='9')||str[head]=='+'){
			if(str[head]=='+')head++;
			int tail=head;
			while(tail<str.size()){
				if(str[tail]>='0'&&str[tail]<='9')tail++;
				else break;
			}
			return safe_atoi(str.substr(head,tail-head));
		}
		else if(str[head]=='-'){
			head++;
			int tail=head;
			while(tail<str.size()){
				if(str[tail]>='0'&&str[tail]<='9')tail++;
				else break;
			}
			string s=str.substr(head,tail-head);
			int k=0,sum=0;
			while(k<s.size()){
			    if(INT_MIN/10>sum)return INT_MIN;
			    else sum*=10;
			    if(INT_MIN+s[k]-'0'>sum)return INT_MIN;
			    else sum-=s[k++]-'0';
			}
			return sum;
		}
		return 0; 
    }
    int safe_atoi(string s){
    	int k=0,sum=0;
    	if(s.size()==0)return 0;
    	while(k<s.size()){
    		if(sum>INT_MAX/10)return INT_MAX;
    		else sum*=10;
    		if(sum>INT_MAX-s[k]+'0')return INT_MAX;
    		else sum+=s[k++]-'0';
		}
		return sum;
	}

9.回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

普通解法思路很简单,反转数字,看它与原数字是否相等。这时候又要用到溢出判断了,因为在反转数字的过程中确实可能溢出。好在有这样一些性质:

  • 反转会溢出的数肯定不是回文数
  • 这题负数肯定不是回文数
    这样程序会简洁不少。
bool isPalindrome(int x) {
		if (x < 0) return false;
		else {
			int sum=0;
			int val = x;
			while (x) {
				if (sum > INT_MAX / 10) return false;
				sum *= 10;
				if (sum > INT_MAX - x % 10) return false;
				sum += x % 10;
				x /= 10;
			}
			if (sum == val)return true;
		}
		return false;
	}

答案区给出了一种更好的解法,可以避免对溢出的检查。方法是只反转一半的数字。反转的一半与另一半相等,那就是回文数。这样就只要简单地判断一下反转的位数是不是一半就可以了。以后有时间可以实现一下这个代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值