Java&LeetCode 初入門——038. 報數
阿新 • • 發佈:2019-01-14
Java&LeetCode 初入門——038. 報數
文內程式碼全部採用JAVA語言。
題目
測試用例
示例 1:
輸入: 1
輸出: "1"
示例 2:
輸入: 4
輸出: "1211"
個人解法
評論區好多小夥伴都說看不懂題目,但是感覺leedcode官方可能對題目重新進行了修改,個人覺得很好理解。就是幾個幾這樣直接向後讀,不再過多解釋。
個人解法嵌套了兩層迴圈,一層是序列n,一層是字串中的字元。
下一個序列需要讀上一個序列的字串。比如n=6時,就讀n=5的“111221”這個序列,讀作:3個1,2個2,1個1,寫成字串就是“312211”。
迴圈啥的都是次要的,主要是讀數,首先字串轉換成字元陣列。然後雙指標,記錄數字和個數(類比026和037,區別在於不需要覆蓋元素,只要統計個數)。個人覺得還是比較好理解,就是寫起來比較麻煩,因為最末位與前面相同的情況以及n=1都是要特殊考慮。目前沒有想到改進演算法的辦法。
程式碼如下,速度不忍直視。執行用時: 37 ms, 在Count and Say的Java提交中擊敗了24.05% 的使用者。
不過學習了一下,發現如果將String全部改成StringBuffer就會大幅增進程式碼執行效率,試了一下,眼珠子都要掉出來。執行用時: 5 ms, 在Count and Say的Java提交中擊敗了77.34% 的使用者。一樣的流程,只是字元型別小小變換了一下,差距這麼大。
public String countAndSay(int n) {
String ansbef="1";
String ans = null;
if (n==1) {
return ansbef;
}
for (int i = 0; i < n-1; i++) {
ans="";
char[] anschar=ansbef.toCharArray();
// System.out.println(anschar);
int k=0;
int j=0;
int times=0;
while (j<anschar.length) {
if (anschar[j]!=anschar[k] ) {
ans=ans+times+anschar[k];
times=0;
k=j;
continue ;
}else if(anschar[j]==anschar[k] && j==anschar.length-1){
times++;
j++;
ans=ans+times+anschar[k];
}else {
times++;
j++;
}
}
ansbef=ans;
// System.out.println(ansbef);
}
return ans;
}
StringBuffer改進後
class Solution {
public String countAndSay(int n) {
StringBuffer ansbef=new StringBuffer("1");
StringBuffer ans = new StringBuffer("");
if (n==1) {
return ansbef.toString();
}
for (int i = 0; i < n-1; i++) {
ans=new StringBuffer("");
char[] anschar=ansbef.toString().toCharArray();
// System.out.println(anschar);
int k=0;
int j=0;
int times=0;
while (j<anschar.length) {
if (anschar[j]!=anschar[k] ) {
ans=ans.append(times).append(anschar[k]);
times=0;
k=j;
continue;
}else if(anschar[j]==anschar[k] && j==anschar.length-1){
times++;
j++;
ans=ans.append(times).append(anschar[k]);
}else {
times++;
j++;
}
}
ansbef=ans;
// System.out.println(ansbef);
}
return ans.toString();
}
}
奇葩解法
本題未給出官方解法。最快的程式碼只需要1ms,但是真的看哭我,直接遍歷有限的測試用例。這麼長的字串,也不知道是哪位大神為了追求全滅複製貼上的答案。
撇開這個不談,範例裡還是有正常解法的。
但是大同小異吧,沒有具體看,但是快的一般都沒有直接用String。String太慢了!!