# subject

Given a string, verify whether it is a palindrome string, only consider alphabetic and numeric characters, and ignore the case of letters.
In this paper, we define an empty string as a valid palindrome string.

# Train of thought 1

Only numbers and letters are considered, so we need to clean the string. Then, we can draw a conclusion by comparing the results before and after using the arcstring in StringBuffer.

# code

```package leetcoder;
//Only numbers and letters are considered (letters ignore case)
class Solution {
public boolean isPalindrome(String s) {
if (s.length()==0)
return true;
else
{
s=s.toLowerCase();//First, change the upper case letters in s to lower case letters
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;//Clean, find numbers and letters
}
StringBuffer a=new StringBuffer(test);
String result=a.reverse().toString();
if (result.equals(test))
return true;
return false;
}
}
}
```

# result

Although A is A, but this algorithm is really rotten, there is no technical content. First of all, the data needs to be converted into upper and lower case, which takes O(n). Then, data cleaning takes O(n). There is no technical content at all, just using java's own method.

# Train of thought 2

Use the double pointer to judge. Set a pointer at the front and the last respectively, and keep moving towards the middle. If the two characters are not equal, return false, otherwise true

# code

```class Solution {
public boolean isPalindrome(String s) {
//Data cleaning
s=s.toLowerCase();
String test="";
for (int i=0;i<s.length();++i)
if (Character.isLetterOrDigit(s.charAt(i)))
test+=s.charAt(i);
//If the length is 0 or 1, it directly returns true to prevent the following subscripts from crossing the boundary
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;
}
}
```

# result

I thought it was a little improved, but I didn't think it was so bad. However, the conversion to lowercase and character searching of optical data cleaning are the same as the algorithm. Even spend more time below, rotten...

# Official double pointer

code:

```class Solution {
public boolean isPalindrome(String s) {
StringBuffer sgood = new StringBuffer();
//The length of this wave is handled in detail, so it is not necessary to calculate it every time, saving time and typically using space for time
int length = s.length();
for (int i = 0; i < length; i++) {
char ch = s.charAt(i);
if (Character.isLetterOrDigit(ch)) {
//When adding, by the way, it turns into a string. What's better than the algorithm above is that you don't have to traverse it twice. It's good. Learn it
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;
}
}
```

# Look at the official and then improve

After reading the official solution, I'll improve my code. When adding, I'll turn to lowercase by the way. Then, I'll turn to the one with the judgment length of 1 or 0 by the way. Because the one with the length of 1 or 0, the right > left will not enter, so it will directly return true. Don't waste time

```class Solution {
public boolean isPalindrome(String s) {
//Data cleaning
String test="";
for (int i=0;i<s.length();++i)
if (Character.isLetterOrDigit(s.charAt(i)))
//Learn the official one. When adding it again, turn to lowercase by the way
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;
}
}
```

# result

It turned out to be the same. At this time, I realized that things are not simple. It must be me. What's wrong? It turned out to be true. The official use of StringBuffer to store code is a variable length String object, and the String I use is an immutable length String. So, every time the official code just adds a new character after it, and I do recreate a new String, no wonder it's so slow.
The relation and difference between String, StringBuffer and StringBuffer

# Code to improve again

```class Solution {
public boolean isPalindrome(String s) {
//Data cleaning
StringBuffer test=new StringBuffer();
for (int i=0;i<s.length();++i)
if (Character.isLetterOrDigit(s.charAt(i)))
//Learn the official one. When adding it again, turn to lowercase by the way
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;
}
}
```

# result

This proves my above idea is right, so data structure is really important. One kind of data organization form is different, the result use time difference is more than 60 times. It's a little bit of a gain, not bad...

Tags: Java

Posted on Fri, 19 Jun 2020 23:38:24 -0400 by divadiva