Leetcode 38 外觀數列
阿新 • • 發佈:2020-07-13
一個變種的斐波那契數列,DP 沒跑了,問題在於如何處理外觀的邏輯。用棧儲存當前計數的元素,遞迴表示:
public final String countAndSay0(int n) { String[] cache = new String[n + 1]; return countAndSay0(n, cache); } public final String countAndSay0(int n, String[] cache) { if (n == 1) { return "1"; }if (n == 2) { return "11"; } if (cache[n] != null) { return cache[n]; } String pre = countAndSay0(n - 1, cache); StringBuilder sb = new StringBuilder(); Stack<Character> stack = new Stack<Character>(); for (inti = 0; i < pre.length(); i++) { //末尾元素處理 if (i == pre.length() - 1) { if (stack.size() == 0) { sb.append("1" + pre.charAt(pre.length() - 1)); } else if (pre.charAt(i) == stack.get(0)) { sb.append(String.valueOf(stack.size()+ 1)).append(String.valueOf(stack.get(0))); } else { sb.append(String.valueOf(stack.size())).append(String.valueOf(stack.get(0))); sb.append("1" + pre.charAt(pre.length() - 1)); } break; } //普通元素處理 if (stack.size() > 0 && pre.charAt(i) != stack.get(0)) { sb.append(String.valueOf(stack.size())).append(String.valueOf(stack.get(0))); stack.clear(); stack.push(pre.charAt(i)); continue; } stack.push(pre.charAt(i)); } stack = null; //記錄快取 cache[n] = sb.toString(); return cache[n]; }
遞推表示:
public final String countAndSay1(int n) { if (n == 1) { return "1"; } String[] cache = new String[n + 1]; cache[1] = "1"; cache[2] = "11"; Stack<Character> stack = new Stack<Character>(); for (int i = 3; i <= n; i++) { String pre = cache[i - 1]; StringBuilder sb = new StringBuilder(); for (int j = 0; j < pre.length(); j++) { //末尾元素處理 if (j == pre.length() - 1) { if (stack.size() == 0) { sb.append("1").append(pre.charAt(pre.length() - 1)); } else if (pre.charAt(j) == stack.get(0)) { sb.append(String.valueOf(stack.size() + 1)).append(String.valueOf(stack.get(0))); } else { sb.append(String.valueOf(stack.size())).append(String.valueOf(stack.get(0))).append("1").append(pre.charAt(pre.length() - 1)); } stack.clear(); break; } //普通元素處理 if (stack.size() > 0 && pre.charAt(j) != stack.get(0)) { sb.append(String.valueOf(stack.size())).append(String.valueOf(stack.get(0))); stack.clear(); stack.push(pre.charAt(j)); continue; } stack.push(pre.charAt(j)); } cache[i] = sb.toString(); } return cache[n]; }
用兩個區域性變數,一個儲存計數元素,一個儲存當前元素個數來代替棧:
public final String countAndSay(int n) { if (n == 1) { return "1"; } if (n == 2) { return "11"; } StringBuilder pre = new StringBuilder("11"); for (int i = 3; i <= n; i++) { StringBuilder sb = new StringBuilder(); char currentChar = pre.charAt(0); int currentNum = 1; for (int j = 1; j < pre.length() + 1; j++) { if (j == pre.length()) { sb.append(currentNum).append(currentChar); break; } if (pre.charAt(j) == currentChar) { currentNum++; continue; } sb.append(currentNum).append(currentChar); currentNum = 1; currentChar = pre.charAt(j); } pre = sb; } return pre.toString(); }