• 第七章 两个面试案例


    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指针、输入字符串为空字符串、输入的字符串中有非数字字符等)。
     
    面试题50:树中两个节点的最低公共祖先
    • 题目:求树中两个节点的最低公共祖先
    • (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;
      • }
     
     
     
     
     
     
  • 相关阅读:
    用ruby抓取网页
    [转] 从项目管理角度看敏捷开发
    ruby学习笔记(9)
    [转] 从项目管理角度看敏捷开发
    ruby学习笔记(8)
    ruby学习笔记(7)
    [转] 什么是敏捷开发
    netbeans tomcat
    maven
    jersey
  • 原文地址:https://www.cnblogs.com/Sungc/p/9343473.html
Copyright © 2020-2023  润新知