【leetCode】leetCode125 Valid Palindrome

(如果想查看最终代码,直接跳到最后,如果想看中间踩过的坑,可以看看过程)

题目如下:

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

Note: For the purpose of this problem, we define empty string as valid palindrome.

Example 1:
Input: "A man, a plan, a canal: Panama"
Output: true
Example 2:
Input: "race a car"
Output: false

很容易想到用对撞指针,即给首尾各定义一个指针。碰到非数字和字母的元素,跳过,直到两个都是字母或者数字,进行比较。

错误一, 一开始忽略了数字(又是低级错误,没读懂数字字母的英文),所以提交后,0p(数字0,不是字母O)测试用例没通过。因为在我的代码里认为数字也是像符号一样可以忽略的。
后来改了判断范围,在本地以下代码通过

package collisionsPointer;

public class ValidPalindrome125 {

	private static boolean isPalindrome (String s) {
		char[] chars = s.toCharArray();
		int l=0;
		int r=chars.length-1;
		while(l<=r) {
			if(!((chars[l]>='0'&&chars[l]<='9')||(chars[l]>='a'&&chars[l]<='z')||(chars[l]>='A'&&chars[l]<='Z'))){
				l++;
				continue;
			}
			if(!((chars[r]>='0'&&chars[r]<='9')||(chars[r]>='a'&&chars[r]<='z')||(chars[r]>='A'&&chars[r]<='Z'))) {
				r--;
				continue;
			}
			//都是字母了
			if(chars[l] != chars[r] && chars[l]+32 != chars[r] && chars[l]-32 != chars[r] ) {
				return false;
			}
			else { //对应位置的字母相同,移动指针
				l++;
				r--;
			}
		}
		
		return true;
	}
	public static void main(String[] args) {
		String s1 = "0p";
		boolean res = isPalindrome(s1);
		System.out.println(res);
	}
}

我为什么在自己的程序里没有直接取非法的范围,而是取到合法的范围然后取非,因为我假定此时并不知道各数字和字母ASCII码的范围(当然自己做题可以百度,假定此时不能百度),所以不好直接取非法的范围。
这个代码在本地{0p}能通过,但是提交到leetCode时,通不过.硬是将0P判断为ture,我也很无奈啊…

不过我发现了自己代码的另外一个bug :
判断两个字符是否相同或者为大小写的时候,直接用了比较两个字符的相等或者±32相等就认为是相同的,同样还是忽略的数字的问题,因为如果是大小写字母的话,这样判断没有问题,但是如果有数字,可能会出现数字的ASCII码+32与某一个字母的ASCII码一样,同样会判断错误。需要分开判断,所以虽然这个用例在本地侥幸判断正确的,但是代码其实是不完全正确的,
然后我就把代码改成了如下:
于是就出现了错误二:

		char[] chars = s.toCharArray();
		int l=0;
		int r=chars.length-1;
		while(l<r) {
			if(!((chars[l]>='0'&&chars[l]<='9')||(chars[l]>='a'&&chars[l]<='z')||(chars[l]>='A'&&chars[l]<='Z'))){
				l++;
				continue;
			}
			if(!((chars[r]>='0'&&chars[r]<='9')||(chars[r]>='a'&&chars[r]<='z')||(chars[r]>='A'&&chars[r]<='Z'))) {
				r--;
				continue;
			}
			//都是字母数字了
			//如果左边是数字,只比较大小
			if((chars[l]>='0'&&chars[l]<='9')) {
				if(chars[l] != chars[r]) {
					return  false;
				}
			}
			//如果左边是字母
			else {
				//如果右边是数字,直接返回
				if((chars[r]>='0'&&chars[r]<='9')) {
					return false;
				}
				//如果右边也是字母,可判断大小写相等
				else {
					if(chars[l] != chars[r] && chars[l]+32 != chars[r] && chars[l]-32 != chars[r] ) {
						return false;
					}
					else { //对应位置的字母相同,移动指针
						l++;
						r--;
					}
				}
			}
		}
		return true;

提交结果:在{1b1}用例时:超时…这个…抓狂啊!

最后,用了java库自带的转换为小写库,这样就省去了复杂的判断过程,战战兢兢地提交:accpted.

Runtime: 3 ms, faster than 96.33% of Java online submissions for Valid Palindrome.
Memory Usage: 37.7 MB, less than 97.71% of Java online submissions for Valid Palindrome.

看百度有些人单独判断了空串或者只有一个字符的字符串,其实没必要,在while处都过不了,直接返回了true.

package collisionsPointer;

public class ValidPalindrome125 {

	private static boolean isPalindrome (String s) {
		s=s.toLowerCase();//就不存在大小写的问题了,直接比较是否相等
		char[] chars = s.toCharArray();
		int l=0;
		int r=chars.length-1;
		while(l<r) {
			if(!((chars[l]>='0'&&chars[l]<='9')||(chars[l]>='a'&&chars[l]<='z')||(chars[l]>='A'&&chars[l]<='Z'))){
				l++;
				continue;
			}
			if(!((chars[r]>='0'&&chars[r]<='9')||(chars[r]>='a'&&chars[r]<='z')||(chars[r]>='A'&&chars[r]<='Z'))) {
				r--;
				continue;
			}
			if(chars[l] != chars[r]) {
				return  false;
			}
			else { //对应位置的字母相同,移动指针
				l++;
				r--;
			}
		}
		return true;
	}
	public static void main(String[] args) {
		String s1 = "p212P";
		boolean res = isPalindrome(s1);
		System.out.println(res);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值