leetcode第九題Palindrome Number 驗證迴文數字

weixin_34308389發表於2019-02-24

Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.

Example 1:

Input: 121
Output: true

Example 2:

Input: -121
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.

Example 3:

Input: 10
Output: false
Explanation: Reads 01 from right to left. Therefore it is not a palindrome.

Follow up:

Coud you solve it without converting the integer to a string?

判斷一個整數是否是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。

示例 1:

輸入: 121
輸出: true

示例 2:

輸入: -121
輸出: false
解釋: 從左向右讀, 為 -121 。 從右向左讀, 為 121- 。因此它不是一個迴文數。

示例 3:

輸入: 10
輸出: false
解釋: 從右向左讀, 為 01 。因此它不是一個迴文數。

進階:

你能不將整數轉為字串來解決這個問題嗎?

思路1

題目中所要驗證的是一個帶有符號的整數的迴文,其將所有符號反過來與原來的資料相同,我們首先會想到將其轉化為字串,再將String方法轉變為Stringbuffer或者Stringbuilder,因為String沒有響應的方法通過字串的reverse方法。
下方解釋string和Stringbuffer,StringBuilder的區別為網上摘要
String 字串常量
StringBuffer 字串變數(執行緒安全)
StringBuilder 字串變數(非執行緒安全)
簡要的說, String 型別和 StringBuffer 型別的主要效能區別其實在於 String 是不可變的物件, 因此在每次對 String 型別進行改變的時候其實都等同於生成了一個新的 String 物件,然後將指標指向新的 String 物件,所以經常改變內容的字串最好不要用 String ,因為每次生成物件都會對系統效能產生影響,特別當記憶體中無引用物件多了以後, JVM 的 GC 就會開始工作,那速度是一定會相當慢的。
而如果是使用 StringBuffer 類則結果就不一樣了,每次結果都會對 StringBuffer 物件本身進行操作,而不是生成新的物件,再改變物件引用。所以在一般情況下我們推薦使用 StringBuffer ,特別是字串物件經常改變的情況下。而在某些特別情況下, String 物件的字串拼接其實是被 JVM 解釋成了 StringBuffer 物件的拼接,所以這些時候 String 物件的速度並不會比 StringBuffer 物件慢,而特別是以下的字串物件生成中, String 效率是遠要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你會很驚訝的發現,生成 String S1 物件的速度簡直太快了,而這個時候 StringBuffer 居然速度上根本一點都不佔優勢。其實這是 JVM 的一個把戲,在 JVM 眼裡,這個
String S1 = “This is only a” + “ simple” + “test”; 其實就是:
String S1 = “This is only a simple test”; 所以當然不需要太多的時間了。但大家這裡要注意的是,如果你的字串是來自另外的 String 物件的話,速度就沒那麼快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
這時候 JVM 會規規矩矩的按照原來的方式去做

在大部分情況下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer執行緒安全的可變字元序列。一個類似於 String 的字串緩衝區,但不能修改。雖然在任意時間點上它都包含某種特定的字元序列,但通過某些方法呼叫可以改變該序列的長度和內容。
可將字串緩衝區安全地用於多個執行緒。可以在必要時對這些方法進行同步,因此任意特定例項上的所有操作就好像是以序列順序發生的,該順序與所涉及的每個執行緒進行的方法呼叫順序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可過載這些方法,以接受任意型別的資料。每個方法都能有效地將給定的資料轉換成字串,然後將該字串的字元追加或插入到字串緩衝區中。append 方法始終將這些字元新增到緩衝區的末端;而 insert 方法則在指定的點新增字元。
例如,如果 z 引用一個當前內容是“start”的字串緩衝區物件,則此方法呼叫 z.append("le") 會使字串緩衝區包含“startle”,而 z.insert(4, "le") 將更改字串緩衝區,使之包含“starlet”。
在大部分情況下 StringBuilder > StringBuffer
java.lang.StringBuilde
java.lang.StringBuilder一個可變的字元序列是5.0新增的。此類提供一個與 StringBuffer 相容的 API,但不保證同步。該類被設計用作 StringBuffer 的一個簡易替換,用在字串緩衝區被單個執行緒使用的時候(這種情況很普遍)。如果可能,建議優先採用該類,因為在大多數實現中,它比 StringBuffer 要快。兩者的方法基本相同。

回到本題如果應用上述方法,那麼請看如下程式碼

 class Solution {
    public boolean isPalindrome(int x) {
        String s = String.valueOf(x);
        StringBuffer bu = new StringBuffer(s).reverse();
        String s1=new String(bu);
        return s.equals(s1);
    }
}
3817938-78b31543c8a83e99.png
圖片.png

雖然可以達到目的但是極其的浪費資源。

思路2

首先,負數肯定是不行,排除了負數後,我們將數字直接抽取倒轉,和第七題相類似。

class Solution {
    public boolean isPalindrome(int x) {
        if(x<0) return false;
        int cope=x;
        int reverse=0;
        while(cope>0){
            reverse=reverse*10+cope%10;
            cope/=10;
        }
        return x==reverse;
    }
}

但是同樣也很浪費資源。

思路三

思考下是否需要計算整個長度,比如 1234321,其實不然,我們只需要計算一半的長度即可,就是在計算過程中的那個逆序數比不斷除 10 的數大就結束計算即可,但是這也帶來了另一個問題,比如 10 的倍數的數 10010,它也會返回 true,所以我們需要對 10 的倍數的數再加個判斷即可,程式碼如下所示。

class Solution {
    public boolean isPalindrome(int x) {
        if( x<0 ||(x!=0 && x%10==0)) return false;
        int halfReverse=0;
        while(x > halfReverse){
            halfReverse=halfReverse*10+ x%10;
            x/=10;
        }
        return x==halfReverse || halfReverse/10==x;
    }
}

相關文章