1. 程式人生 > >LeetCode 刷題記錄(5,6,7)—Java語言

LeetCode 刷題記錄(5,6,7)—Java語言

5. 最長迴文子串

給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為1000。

示例 1:

輸入: “babad”
輸出: “bab”
注意: “aba”也是一個有效答案。
示例 2:

輸入: “cbbd”
輸出: “bb”

思路

這道題最直接的解法就是中心擴散法,即從每個字元或者每個兩個字元間開始判斷左右兩邊是否相等,不過時間複雜度太高,最適合的還是Manacher演算法,此演算法在中心擴散演算法的基礎上,通過簡化一下重複判斷操作使其時間複雜度為O(N)。具體的方法是利用之前判斷的迴文串的對稱性省略一些不必要的判斷。

程式碼

class Solution {
    public
String longestPalindrome(String s) { StringBuilder str = new StringBuilder("!#"); for(int i=0;i<s.length();i++){ str.append(s.charAt(i)); str.append("#"); } str.append("@"); String t = str.toString(); int p[] = new int[t.length()]; int
right=0,center=0,resCenter=0,resLength=0; for(int i=1;i<t.length()-1;i++){ p[i] = right>i?Math.min(p[2*center-i],right-i):1; while(t.charAt(i+p[i])==t.charAt(i-p[i]))++p[i]; if(right < i+p[i]){ right = i+p[i]; center = i; } if
(resLength<p[i]){ resLength = p[i]; resCenter = i; } } int start = (resCenter-resLength)/2; return s.substring(start,start+resLength-1); } }

6. Z字形變換

將字串 “PAYPALISHIRING” 以Z字形排列成給定的行數:

P A H N
A P L S I I G
Y I R
之後從左往右,逐行讀取字元:”PAHNAPLSIIGYIR”

實現一個將字串進行指定行數變換的函式:

string convert(string s, int numRows);
示例 1:

輸入: s = “PAYPALISHIRING”, numRows = 3
輸出: “PAHNAPLSIIGYIR”
示例 2:

輸入: s = “PAYPALISHIRING”, numRows = 4
輸出: “PINALSIGYAHRPI”
解釋:

P I N
A L S I G
Y A H R
P I

思路

首先字串是排列的是一個躺著的Z字形其實說成是N字形更為明顯,多看看示例不難會發現一點特徵。N字形是迴圈排列的,一個迴圈週期數為2*numRows-2;那麼只需要抓住一個週期的特點即可解決問題。對於第一行和最後一行的數來說,直接從第一個數開始加上一個迴圈週期既可以得到對應的下一個數。而中間的幾行每一行對應兩個數,而且自上而下每一行的兩個數下標只差為2*numRows-2*(行號+1),這裡行號從0開始到numRows-1。那麼利用這個週期特徵就可以完成每一行字元的提取,然後自上而下提取所有行,即可得到結果

程式碼

其中num為一個週期內包含的字元個數,temp為獲取當前週期內此行對應了下一個字元(只有第一行和最後一行中間的行的才有下一個字元)。第一層迴圈是行號迴圈,第二層迴圈是層次迴圈獲取每一行中所有的字元。

class Solution {
    public String convert(String s, int numRows) {
        if(numRows<=1)
            return s;
        int num = 2*numRows-2;
        StringBuilder str = new StringBuilder();
        for(int i=0;i<numRows;i++)
            for(int j=i;j<s.length();j+=num){
                str.append(s.charAt(j));
                int temp = j+num-2*i;
                if(i!=0&&i!=numRows-1&&temp<s.length())
                    str.append(s.charAt(temp)); 
            }
        return str.toString();
    }
}

7. 反轉整數

給定一個 32 位有符號整數,將整數中的數字進行反轉。

示例 1:

輸入: 123
輸出: 321
示例 2:

輸入: -123
輸出: -321
示例 3:

輸入: 120
輸出: 21
注意:

假設我們的環境只能儲存 32 位有符號整數,其數值範圍是 [−231, 231 − 1]。根據這個假設,如果反轉後的整數溢位,則返回 0。

思路

這道思路很簡單通過對輸入值每位數拆分再重組即可達到反轉的效果。但是需要注意的點就是反轉溢位,比如int的最大值是2147483647,反轉之後為7463847412,明顯已經超過int值的取值範圍,那麼需要返回0,我這裡直接通過使用long型別來儲存,在反轉之後判斷是否溢位,如果溢位則返回0,反之就返回反轉後的數字。

class Solution {
    public int reverse(int x) {
        long num = Math.abs(x);
        boolean flag = x<0;
        long res=0;
        while(num>0){
            res = res*10+num%10;
            num/=10;
        }
        if(!flag&&res>Integer.MAX_VALUE
           ||flag&&res*-1<Integer.MIN_VALUE){
            return 0;
        }
        return flag?(int)(-1*res):(int)res;
    }
}