第七章 兩個面試案例
阿新 • • 發佈:2018-07-20
== 一個 nbsp 復雜 else font null 整數 lse
7.1 案例一
面試題49:把字符串轉換成整數
- 題目:將一個字符串轉換成一個整數,要求不能使用字符串轉換整數的庫函數。 數值為0或者字符串不是一個合法 的數值則返回0
- 思路:若為負數,則輸出負數,字符0對應48,9對應57,不在範圍內則返回false。
- 代碼實現
-
- public class TestMain {
- public static void main(String[] args) {
- TestMain t = new TestMain();
- System.out.println(t.StrToInt("12"));
- }
-
public int StrToInt(String str) {
- if (str == null || str.length() == 0)
- return 0;
- int mark = 0;
- int start = 0;
- int number = 0;
- char[] chars = str.toCharArray();
- if (chars[0] == ‘-‘) {
- mark = 1;
- start = 1;
- } else if (chars[0] == ‘+‘) {
- start = 1;
- }
- for (int i = start; i < chars.length; i++) {
-
if (chars[i] < 48 || chars[i] > 57) {
- return 0;
- }
- number = number * 10 + chars[i] - 48;
- }
- return mark == 0 ? number : -number;
- }
- }
- 測試用例:
-
- 功能測試(輸入的字符串表示正數、負數和0)。
- 邊界值測試(最大的正整數、最小的負整數)。
- 特殊輸入測試(輸入字符串為NULL指針、輸入字符串為空字符串、輸入的字符串中有非數字字符等)。
- 題目:求樹中兩個節點的最低公共祖先
- (1)樹是二叉搜索樹
- 思路:從樹的根節點開始遍歷,如果根節點的值大於其中一個節點,小於另外一個節點,則根節點就是最低公 共祖先。否則如果根節點的值小於兩個節點的值,則遞歸求根節點的右子樹,如果大於兩個節點的值則遞歸求 根的左子樹。如果根節點正好是其中的一個節點,那麽說明這兩個節點在一條路徑上,所以最低公共祖先則是 根節點的父節點,時間復雜度是O(logn),空間復雜度是O(1)
- 代碼實現
-
- class TreeNode {
- public int value;
- public TreeNode left;
- public TreeNode right;
- public TreeNode(int value) {
- this.value = value;
- }
- public TreeNode() {
- }
- }
- public class TestTree {
- public static int n;
- ArrayList<ArrayList<Integer>> resultList = new ArrayList<ArrayList<Integer>>();
- ArrayList<Integer> list = new ArrayList<Integer>();
- public static void main(String[] args) {
- int[] array = new int[] { 7,1,0,3,2,0,0,5,0,0,8,0,9,0,0};
- TestTree t = new TestTree();
- TreeNode root = t.CreateTreeBinary(new TreeNode(), array);
- System.out.println(t.getLowestCommonAncestor(root, root, new TreeNode(2), new TreeNode(5)).value);
- }
- public TreeNode CreateTreeBinary(TreeNode treeNode, int[] array) {
- if (array[n] == 0) {
- n++;
- return null;
- } else {
- treeNode.value = array[n++];
- treeNode.left = CreateTreeBinary(new TreeNode(0), array);
- treeNode.right = CreateTreeBinary(new TreeNode(0), array);
- return treeNode;
- }
- }
- public static TreeNode getLowestCommonAncestor(TreeNode rootParent, TreeNode root,
- TreeNode node1, TreeNode node2) {
- if (root == null || node1 == null || node2 == null) {
- return null;
- }
- if ((root.value - node1.value) * (root.value - node2.value) < 0) {
- return root;
- } else if ((root.value - node1.value) * (root.value - node2.value) > 0) {
- TreeNode newRoot = ((root.value > node1.value) && (root.value > node2.value)) ? root.left
- : root.right;
- return getLowestCommonAncestor(root, newRoot, node1, node2);
- } else {
- return rootParent;
- }
- }
- }
- (2)若樹是普通樹,但有指向父節點的指針
- 思路:兩個節點如果在兩條路徑上,類似於求兩個鏈表的第一個公共節點。由於每個節點的深度最多為logn,所以時間復雜度為O(logn),空間復雜度O(1)
- 思路二:循環兩次 第一次長度差 第二次求值
- 代碼實現
-
- public BinaryTreeNode getLowestCommonAncestor1(BinaryTreeNode root, BinaryTreeNode node1, BinaryTreeNode node2) {
- if (root == null || node1 == null || node2 == null) {
- return null;
- }
- int depth1 = findTheDepthOfTheNode(root, node1, node2);
- if (depth1 == -1) {
- return node2.parentNode;
- }
- int depth2 = findTheDepthOfTheNode(root, node2, node1);
- if (depth2 == -1) {
- return node1.parentNode;
- }
- // p指向較深的節點q指向較淺的節點
- BinaryTreeNode p = depth1 > depth2 ? node1 : node2;
- BinaryTreeNode q = depth1 > depth2 ? node2 : node1;
- int depth = Math.abs(depth1 - depth2);
- while (depth > 0) {
- p = p.parentNode;
- depth--;
- }
- while (p != q) {
- p = p.parentNode;
- q = q.parentNode;
- }
- return p;
- }
- // 求node1的深度,如果node1和node2在一條路徑上,則返回-1,否則返回node1的深度
- public int findTheDepthOfTheNode(BinaryTreeNode root, BinaryTreeNode node1, BinaryTreeNode node2) {
- int depth = 0;
- while (node1.parentNode != null) {
- node1 = node1.parentNode;
- depth++;
- if (node1 == node2) {
- return -1;
- }
- }
- return depth;
- }
- (3)若樹是普通樹,並沒有指向父節點的指針
- 思路:用棧來實現類似於指向父節點指針的功能,獲取node節點的路徑時間復雜度為O(n),所以總的時間復雜度是O(n),空間復雜度是O(logn)
- 代碼實現
-
- public BinaryTreeNode getLowestCommonAncestor2(BinaryTreeNode root, BinaryTreeNode node1, BinaryTreeNode node2) {
- if (root == null || node1 == null || node2 == null) {
- return null;
- }
- Stack<BinaryTreeNode> path1 = new Stack<BinaryTreeNode>();
- boolean flag1 = getThePathOfTheNode(root, node1, path1);
- if (!flag1) {// 樹上沒有node1節點
- return null;
- }
- Stack<BinaryTreeNode> path2 = new Stack<BinaryTreeNode>();
- boolean flag2 = getThePathOfTheNode(root, node2, path2);
- if (!flag2) {// 樹上沒有node2節點
- return null;
- }
- if (path1.size() > path2.size()) { // 讓兩個路徑等長
- while (path1.size() != path2.size()) {
- path1.pop();
- }
- } else {
- while (path1.size() != path2.size()) {
- path2.pop();
- }
- }
- if (path1 == path2) {// 當兩個節點在一條路徑上時
- path1.pop();
- return path1.pop();
- } else {
- BinaryTreeNode p = path1.pop();
- BinaryTreeNode q = path2.pop();
- while (q != p) {
- p = path1.pop();
- q = path2.pop();
- }
- return p;
- }
- }
- // 獲得根節點到node節點的路徑
- public boolean getThePathOfTheNode(BinaryTreeNode root, BinaryTreeNode node, Stack<BinaryTreeNode> path) {
- path.push(root);
- if (root == node) {
- return true;
- }
- boolean found = false;
- if (root.leftNode != null) {
- found = getThePathOfTheNode(root.leftNode, node, path);
- }
- if (!found && root.rightNode != null) {
- found = getThePathOfTheNode(root.rightNode, node, path);
- }
- if (!found) {
- path.pop();
- }
- return found;
- }
第七章 兩個面試案例