/** * * Shortest Solution: How to express only one child? case 1: left child is not null; in other words, * there is a left child: node.left!=null case 2: right child is not null; node.right!=null) case 3: node has two child (node.left!=null) && (node.right!=null) case 4: node has only one child ( * A: left child only, * B: right child only, * one true, one false; * left child existed != right child existed; * cannot be both false or both true) (node.left!=null)!=(node.right!=null) case 5: at least one child (one child or two child) (node.left!=null) || (node.right!=null) * 这道题非常好, 通过这道题, 面试问你: 优化代码; * 这时你可以推敲, 哪句代码会有错误, 可能错在哪里. * 提示:有很强的逻辑思维能力, * 想到只有一个孩子, 可以表示为一句话: * (node.left!=null)!=(node.right!=null) */ public static int countOneChildNode(Node node) { if (node == null) return 0; return (((node.left != null) != (node.right != null) ? 1 : 0) + countOneChildNode(node.left) + countOneChildNode(node.right)); }
/** * More readable code. * */ public static int countOneChildNode2(Node node) { if (node == null) return 0; bool having_l_child = node.left !=null; bool having_r_child = node.right != null; // either left child or right child existing, // one true, another is false; // two of them are true - two children // none of them is true - no child bool oneChildOnly = having_l_child != having_r_child; return (oneChildOnly ? 1 : 0) + countOneChildNode2(node.left) + countOneChildNode2(node.right); }
static void Main(string[] args) { /* Updated on July 9, 2015 * Test case: * 1 * 2 3 * 4 5 6 * Result: one child only - value is 1, node is 3 */ Node n1 = new Node(1); n1.left = new Node(2); n1.right = new Node(3); n1.left.left = new Node(4); n1.left.right = new Node(5); n1.right.left = new Node(6); int r1 = countOneChildNode1(n1); int r2 = countOneChildNode(n1); /* * Test case 2: * 1 * 2 * 3 * result: 2 */ Node t1 = new Node(1); t1.left = new Node(2); t1.left.right = new Node(3); int t3 = countOneChildNode(t1); int val4 = countOneChildNode(t1); }
/** Latest update: * The solution needs some improvement. * See how good you are to improve it! * julia comment: * 1. Since first line is the discussion of “node==null”, * so, it is safe to call the function with null pointer; * 2. A node may have 1 child, 2 children or no children, 3 cases; * 3. We need to find out 1 child only; * need to simplify the checking * 4. The code is too much to read: * 4.1. function call 4 times * 4.2 left!=null twice, right!=null twice, "+ 1" twice * 4.3 if cases - how to merge some cases - minimum 2 cases * Also, 0 repeats twice. * Overall, there is too much places which may go wrong. * */ public static int countOneChildNode1(Node node) { if (node == null) return 0; if (node.left != null && node.right != null) // two children { return countOneChildNode1(node.left) + countOneChildNode1(node.right); } else if (node.left != null) // left child only { return countOneChildNode1(node.left) + 1; } else if (node.right != null) // right child only { return countOneChildNode1(node.right) + 1; } else // no left child, no right child return 0; }