LeetCode演算法題-Valid Palindrome(Java實現)
這是悅樂書的第174次更新,第176篇原創
01 看題和準備
今天介紹的是LeetCode演算法題中Easy級別的第33題(順位題號是125)。給定一個字串,確定它是否是迴文,只考慮字母數字字元並忽略大小寫。空字串是有效迴文。例如:
輸入:“A man, a plan, a canal: Panama”
輸出:true
輸入:“race a car”
輸出:false
本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。
02 第一種解法
特殊情況一:當傳入的字串為null時,直接返回true。
特殊情況二:當傳入的字串去掉空格後的長度為0時,直接返回true。
正常情況:因為傳入的字串可能包含特殊字元,如空格、","、":"、"?"等,這些都是非字母、數字字元,這對我們的判斷增加了難度,但是其核心思想是不變的。
首先可以將字串全部轉為小寫,然後建立兩個索引,一個從前往後,一個從後往前,依次獲取相應的字元,在判斷是否相等前,先要判斷獲取到的字元是否是字母、數字,不是字母和數字,索引向前移動一位,否則判斷兩個字元是否相等,不等於直接返回false,如果等於,索引向前移動一位,繼續迴圈,直到遍歷完判斷完所有的字元。
public boolean isPalindrome(String s) { if (s == null || s.trim().length() == 0) { return true; } s = s.toLowerCase(); int left = 0; int right = s.length() - 1; while (left <= right) { Character c1 = s.charAt(left); Character c2 = s.charAt(right); if (!isAlphaNumeric(c1)) { left++; }else if (!isAlphaNumeric(c2)) { right--; } else { if (c1 != c2) { return false; } left++; right--; } } return true; } public static boolean isAlphaNumeric(Character c){ if (c >= 'a' && c<= 'z') { return true; } if (c >= 'A' && c<= 'Z') { return true; } if (c >= '0' && c<= '9') { return true; } return false; }
03 第二種解法
此解法和第一種解法思路一樣,但是藉助了Character.isLetterOrDigit()方法來幫我們判斷獲取到的字元是否為字母或者數字。
public boolean isPalindrome2(String s) { if (s == null || s.trim().length() == 0) { return true; } s = s.toLowerCase(); int left = 0; int right = s.length() - 1; while (left <= right) { Character c1 = s.charAt(left); Character c2 = s.charAt(right); if (!Character.isLetterOrDigit(c1)) { left++; } else if (!Character.isLetterOrDigit(c2)) { right--; } else { if (c1 != c2) { return false; } left++; right--; } } return true; }
04 另類的解法
此解法不那麼正規,利用字串本身的一些方法以及StringBuffer類的reverse()方法來完成判斷。先將傳入的字串轉為小寫,並且去掉空格,然後利用正則,將非字母、數字的其他字元全部替換掉,再利用StringBuffer的reverse()方法,最後判斷兩字串是否相等。
public boolean isPalindrome3(String s) {
if (s == null || s.trim().length() == 0) {
return true;
}
String newString = s.toLowerCase().replace(" ", "").replaceAll("\\W", "");
String newString2 = new StringBuffer(newString).reverse().toString();
return newString.equals(newString2);
}
05 測試與驗證
對於上面三種方法,編寫了部分測試程式碼,如下:
public static void main(String[] args) {
Easy_125_ValidPalindrome instance = new Easy_125_ValidPalindrome();
String arg = "A man, a plan, a canal: Panama";
long start = System.nanoTime();
boolean result = instance.isPalindrome(arg);
long end = System.nanoTime();
System.out.println("isPalindrome---輸入:"+arg+" , 輸出:"+result+" , 用時:"+(end-start)/1000+"微秒");
long start2 = System.nanoTime();
boolean result2 = instance.isPalindrome2(arg);
long end2 = System.nanoTime();
System.out.println("isPalindrome2---輸入:"+arg+" , 輸出:"+result2+" , 用時:"+(end2-start2)/1000+"微秒");
long start3 = System.nanoTime();
boolean result3 = instance.isPalindrome3(arg);
long end3 = System.nanoTime();
System.out.println("isPalindrome3---輸入:"+arg+" , 輸出:"+result3+" , 用時:"+(end3-start3)/1000+"微秒");
}
測試結果如下:
isPalindrome---輸入:A man, a plan, a canal: Panama , 輸出:false , 用時:191微秒
isPalindrome2---輸入:A man, a plan, a canal: Panama , 輸出:true , 用時:27微秒
isPalindrome3---輸入:A man, a plan, a canal: Panama , 輸出:true , 用時:1566微秒
06 小結
此三種解法中最優的是解法二,最差的是解法三,如果筆試或者面試碰到此類題,以第二種解法作答較好。
以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!