工慾善其事必先利其器
答題有幾個難點要點:
- 識別出題目類型
- 選擇實現所需要的數據結構
- 針對非正常情況的處理
- 提交通過
識別出題目類型,一般還是比較容易做到的,總共也就那麼些類型。
數據結構則相對困難,許多題目只是用了該數據結構的思想,並沒有實際去構建該數據結構。
魯棒性只要細心處理,一般不會導致答題失敗。
而提交通過是最難的,因爲完成了123仍然不能保證你的思路是正確的,而此時你已經花費了大量時間精力在這種錯誤答題上面了。
必須認識到,調bug是必須掌握的一項技能,在有一定算法基礎後,調bug能力纔是決定最終是否成功解答的關鍵。千萬不要妄想在瞭解思路的情況下,不調bug也能正確解答。
搭建好答題環境
搭建好一個如下的工程
race中則是爲本次解答所搭建好的環境。
race-temp中放着一些調試工具和套路模板,包名上其了中文名方便查找。
樹節點輸入模板
當題目是樹的時候,你是否一臉懵逼,要麼思路清晰,稍作調整就完成解答,要麼找不到思路,寫完不知道錯哪裏,運氣好盲調半天解決了,運氣不好只能gg了。
假如給你一個打印樹的方法,打印如下,調試起來是否更加得心應手呢?
│ ┌——15
│ ┌——7
│ ┌——20
│ │ └——15
│ │ │ ┌——20
│ │ └——20
│ │ │ ┌——7
│ │ └——7
│ │ └——15
└——3
└——9
參考自LeetCode的playground代碼,其中一些空格要自行調整一下,輸出纔對齊。如下:
package 樹節點輸入模板;
import java.io.*;
import java.util.*;
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
// 打印一下
MainClass.prettyPrintTree(root);
List<List<Integer>> list = new ArrayList<List<Integer>>();
list.add(Arrays.asList(1, 2, 3));
return list;
}
}
//===================================================================================================
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class MainClass {
public static void main(String[] args) throws IOException {
String filePath = "E:\\idea-project\\leetcode\\race-temp\\src\\main\\java\\樹節點輸入模板\\test1.txt";
FileInputStream is = new FileInputStream(new File(filePath));
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = in.readLine()) != null) {
TreeNode root = stringToTreeNode(line);
List<List<Integer>> ret = new Solution().zigzagLevelOrder(root);
String out = int2dListToString(ret);
System.out.print(out);
}
}
public static TreeNode stringToTreeNode(String input) {
input = input.trim();
input = input.substring(1, input.length() - 1);
if (input.length() == 0) {
return null;
}
String[] parts = input.split(",");
String item = parts[0];
TreeNode root = new TreeNode(Integer.parseInt(item));
Queue<TreeNode> nodeQueue = new LinkedList<>();
nodeQueue.add(root);
int index = 1;
while (!nodeQueue.isEmpty()) {
TreeNode node = nodeQueue.remove();
if (index == parts.length) {
break;
}
item = parts[index++];
item = item.trim();
if (!item.equals("null")) {
int leftNumber = Integer.parseInt(item);
node.left = new TreeNode(leftNumber);
nodeQueue.add(node.left);
}
if (index == parts.length) {
break;
}
item = parts[index++];
item = item.trim();
if (!item.equals("null")) {
int rightNumber = Integer.parseInt(item);
node.right = new TreeNode(rightNumber);
nodeQueue.add(node.right);
}
}
return root;
}
public static String integerArrayListToString(List<Integer> nums, int length) {
if (length == 0) {
return "[]";
}
String result = "";
for (int index = 0; index < length; index++) {
Integer number = nums.get(index);
result += Integer.toString(number) + ", ";
}
return "[" + result.substring(0, result.length() - 2) + "]";
}
public static String integerArrayListToString(List<Integer> nums) {
return integerArrayListToString(nums, nums.size());
}
public static String int2dListToString(List<List<Integer>> nums) {
StringBuilder sb = new StringBuilder("[");
for (List<Integer> list : nums) {
sb.append(integerArrayListToString(list));
sb.append(",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
private static void prettyPrintTree(TreeNode node, String prefix, boolean isLeft) {
if (node == null) {
System.out.println("Empty tree");
return;
}
if (node.right != null) {
prettyPrintTree(node.right, prefix + (isLeft ? "│ " : " "), false);
}
System.out.println(prefix + (isLeft ? "└——" : "┌——") + node.val);
if (node.left != null) {
prettyPrintTree(node.left, prefix + (isLeft ? " " : "│ "), true);
}
}
/**
* 把樹以可視化方式打印出來
* @param node
*/
public static void prettyPrintTree(TreeNode node) {
prettyPrintTree(node, "", true);
// 分割線搞搞
System.out.println("==================================================================================");
}
}
總結
自此,已經做好了相當的準備工作了。調試方面,只能各憑本事了,並無招式。按照此模式繼續進行擴充,踏上搞事之路吧。