Leetcode-125. Verify palindrome string

Verify palindrome string subject Train of thought 1 code result Train of thought 2 code result Official double pointer ...

Verify palindrome string

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; } }
Official results

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...

19 June 2020, 23:38 | Views: 8485

Add new comment

For adding a comment, please log in
or create account

0 comments