1. 程式人生 > >LeetCode刷題筆記(二)

LeetCode刷題筆記(二)

4. 兩個排序陣列的中位數

給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2 

請找出這兩個有序陣列的中位數。要求演算法的時間複雜度為 O(log (m+n)) 。

你可以假設 nums1 和 nums2 不同時為空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

中位數是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

中位數是 (2 + 3)/2 = 2.5

思路分析:利用空間來直接定位到中位數的位置,建立一個大小為nums1和nums2總長度的陣列,依次將有序數字填入新建陣列,直接返回中位數即可。

class Solution {     public double findMedianSortedArrays(int[] nums1, int[] nums2) {         int m = nums1.length;         int n = nums2.length;         int[] tmp = new int[m+n];                  int i = 0,j=0,count = 0;;         while(i<m && j<n){             if(nums1[i]<=nums2[j]){                 tmp[count++] = nums1[i++];             }else{                 tmp[count++] = nums2[j++];             }         }         while(i<m){             tmp[count++] = nums1[i++];         }         while(j<n){             tmp[count++] = nums2[j++];         }         return count%2==0?(tmp[(count-1)/2]+tmp[count/2])*1.0/2:tmp[(count-1)/2];     } }

5. 最長迴文子串

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

示例 1:

輸入: "babad"
輸出: "bab"
注意: "aba"也是一個有效答案。

示例 2:

輸入: "cbbd"
輸出: "bb"

Dynamic Programming

To improve over the brute force solution, we first observe how we can avoid unnecessary re-computation while validating palindromes. Consider the case "ababa". If we already knew that "bab" is a palindrome, it is obvious that "ababa" must be a palindrome since the two left and right end letters are the same.

We define P(i,j)P(i,j) as following:

P(i,j)={true,false,if the substring Si…Sj is a palindromeotherwise. P(i,j)={true,if the substring Si…Sj is a palindromefalse,otherwise. 

Therefore,

P(i, j) = ( P(i+1, j-1) \text{ and } S_i == S_j )P(i,j)=(P(i+1,j−1) and Si​==Sj​)

The base cases are:

P(i, i) = trueP(i,i)=true

P(i, i+1) = ( S_i == S_{i+1} )P(i,i+1)=(Si​==Si+1​)

This yields a straight forward DP solution, which we first initialize the one and two letters palindromes, and work our way up finding all three letters palindromes, and so on...

class Solution {     public String longestPalindrome(String s) {         int n = s.length();         String res = "";         boolean[][] dp = new boolean[n][n];         for(int i = n-1;i>=0;i--){             for(int j = i; j<n;j++){                 dp[i][j] = s.charAt(i)==s.charAt(j) && (j-i<2 || dp[i+1][j-1]);                 if(dp[i][j] && j-i+1>res.length()){                     res = s.substring(i,j+1);                 }             }         }         return res;     } }

8. 字串轉整數 (atoi)

實現 atoi,將字串轉為整數。

該函式首先根據需要丟棄任意多的空格字元,直到找到第一個非空格字元為止。如果第一個非空字元是正號或負號,選取該符號,並將其與後面儘可能多的連續的數字組合起來,這部分字元即為整數的值。如果第一個非空字元是數字,則直接將其與之後連續的數字字元組合起來,形成整數。

字串可以在形成整數的字元後面包括多餘的字元,這些字元可以被忽略,它們對於函式沒有影響。

當字串中的第一個非空字元序列不是個有效的整數;或字串為空;或字串僅包含空白字元時,則不進行轉換。

若函式不能執行有效的轉換,返回 0。

說明:

假設我們的環境只能儲存 32 位有符號整數,其數值範圍是 [−231,  231 − 1]。如果數值超過可表示的範圍,則返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:

輸入: "42"
輸出: 42

示例 2:

輸入: "   -42"
輸出: -42
解釋: 第一個非空白字元為 '-', 它是一個負號。
     我們儘可能將負號與後面所有連續出現的數字組合起來,最後得到 -42 。

示例 3:

輸入: "4193 with words"
輸出: 4193
解釋: 轉換截止於數字 '3' ,因為它的下一個字元不為數字。

示例 4:

輸入: "words and 987"
輸出: 0
解釋: 第一個非空字元是 'w', 但它不是數字或正、負號。
     因此無法執行有效的轉換。

示例 5:

輸入: "-91283472332"
輸出: -2147483648
解釋: 數字 "-91283472332" 超過 32 位有符號整數範圍。 
     因此返回 INT_MIN (−231) 。

思路分析:記錄正負,依次取值疊加即可遇到非數字即停止。

class Solution {     public int myAtoi(String str) {                  str = str.trim();         if(str.isEmpty()||str.length()==0)             return 0;         int len = str.length(), i = 0,res = 0,sign = 1;         if(str.charAt(i)=='-' || str.charAt(i)=='+'){             sign = str.charAt(i++) == '+' ? 1 : -1;         }         for(;i<len;i++){             int tmp = str.charAt(i)-'0';             if(tmp<0 ||tmp>9)                 break;             if(res>Integer.MAX_VALUE/10 || (res==Integer.MAX_VALUE/10 && Integer.MAX_VALUE%10<tmp))                 return sign==1?Integer.MAX_VALUE:Integer.MIN_VALUE;             else                 res = res*10+tmp;         }         return res*sign;     } }