Leetcode——125.验证回文串

验证回文串

  • 题目
  • 思路1
  • 代码
  • 结果
  • 思路2
  • 代码
  • 结果
  • 官方双指针
  • 官方结果
  • 看了官方之后再改进
  • 结果
  • 再再次改进的代码
  • 结果

题目

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。

思路1

只考虑数字和字母,所以要对字符串进行一些清洗,然后,利用StringBuffer里面的反正字符串,将前后结果一比较,就可以得出结论了。

代码

package leetcoder;
//本题只考虑数字和字母(字母忽略大小写)
class Solution {
    public boolean isPalindrome(String s) {
        if (s.length()==0)
            return true;
        else
        {
        s=s.toLowerCase();//先将s中的大写字母转为小写字母
        String test = "";
        char c;
        for (int i=0;i<s.length();++i)
        {
            c=s.charAt(i);
            if ((c>='0'&& c<='9')||(c>='a'&&c<='z'))
                test+=c;//清洗,找出数字和字母
        }
        StringBuffer a=new StringBuffer(test);
        String result=a.reverse().toString();
        if (result.equals(test))
            return true;
        return false;
        }
    }
}

结果

虽然A是A了,但是这算法是真的烂,完全没有技术含量的。首先,数据要转化成为大小写,那个地方耗时O(n),然后,再进行数据清洗,又耗时O(n),完全没有技术含量,只是利用java自带的方法而已。
Leetcode——125.验证回文串_第1张图片

思路2

利用双指针来进行判断,在最前面和最后面分别设置一个指针,不断往中间靠拢,如果两个字符不相等则返回false,否则为true

代码

class Solution {
    public boolean isPalindrome(String s) {
        //数据清洗
        s=s.toLowerCase();
        String test="";
        for (int i=0;i<s.length();++i)
            if (Character.isLetterOrDigit(s.charAt(i)))
                test+=s.charAt(i);
//长度为0,或者为1都是直接返回true,防止下面的下标越界
        if (test.length()==0||test.length()==1)
            return true;

        int left=0;
        int right=test.length()-1;
        while (right>left)
        {
            if (test.charAt(left)!=test.charAt(right))
                return false;
            else
            {
                ++left;
                --right;
            }
        }
        return true;
    }
}

结果

我还以为有点改进的,想不到还是这么烂。不过也是,光数据清洗的转小写和找字符,都跟上个算法一样了。甚至下面花费的时间更多,烂。。。
Leetcode——125.验证回文串_第2张图片


官方双指针

代码:

class Solution {
    public boolean isPalindrome(String s) {
        StringBuffer sgood = new StringBuffer();
        //这波长度处理得很细节,不用每次都计算一次,节省时间,典型利用空间换时间
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char ch = s.charAt(i);
            if (Character.isLetterOrDigit(ch)) {
            //添加的时候,顺便转成字符串,比我上面那个算法好的地方,就是不用遍历两遍,挺好的,学起来
                sgood.append(Character.toLowerCase(ch));
            }
        }
        int n = sgood.length();
        int left = 0, right = n - 1;
        while (left < right) {
            if (Character.toLowerCase(sgood.charAt(left)) != Character.toLowerCase(sgood.charAt(right))) {
                return false;
            }
            ++left;
            --right;
        }
        return true;
    }
}

官方结果

Leetcode——125.验证回文串_第3张图片

看了官方之后再改进

看了官方题解之后,我再改进我的代码,在添加的时候顺便转小写了,然后,把判断长度为1或者为0的那个顺便去了,因为长度为1或者0,那个right>left不会进入,所以直接返回true。不用浪费时间

class Solution {
    public boolean isPalindrome(String s) {
        //数据清洗
        String test="";
        for (int i=0;i<s.length();++i)
            if (Character.isLetterOrDigit(s.charAt(i)))
                //学习官方的,再添加的时候,顺便转小写
                test+=Character.toLowerCase(s.charAt(i));

        int left=0;
        int right=test.length()-1;
        while (right>left)
        {
            if (test.charAt(left)!=test.charAt(right))
                return false;
            else
            {
                ++left;
                --right;
            }
        }
        return true;
    }
}

结果

Leetcode——125.验证回文串_第4张图片
结果还是这个样子。这个时候,我就意识到事情不简单。肯定是我哪里有问题了?结果一想,还真是。官方利用StringBuffer来存储代码,它是一个可变长度的字符串对象,而我用的String是一个不可变长度的字符串。所以,每次官方代码只是在后面新增一个新的字符,而我确实重新创建一个新的字符串,怪不得这么慢。
String,StringBuffer和StringBuder的联系与区别

再再次改进的代码

class Solution {
    public boolean isPalindrome(String s) {
        //数据清洗
        StringBuffer test=new StringBuffer();
        for (int i=0;i<s.length();++i)
            if (Character.isLetterOrDigit(s.charAt(i)))
                //学习官方的,再添加的时候,顺便转小写
                test.append(Character.toLowerCase(s.charAt(i)));

      /*  if (test.length()==0||test.length()==1)
            return true;*/

        int left=0;
        int right=test.length()-1;
        while (right>left)
        {
            if (test.charAt(left)!=test.charAt(right))
                return false;
            else
            {
                ++left;
                --right;
            }
        }
        return true;
    }
}

结果

这个就证明了我上面的想法是对的,所以,数据结构真的很重要呀。一种数据的组织形式不同,结果使用时间相差了60多倍。总算有点收获,还不错。。。
Leetcode——125.验证回文串_第5张图片

你可能感兴趣的:(LeetCode)