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 中最長的迴文子串。你可以假設 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; } }