国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

我的面試準備過程--二叉樹(更新中)

Amio / 820人閱讀

摘要:寫在最前面導師貪腐出逃美國,兩年未歸,可憐了我。拿了小米和美團的,要被延期,失效,工作重新找。把準備過程紀錄下來,共勉。

寫在最前面

導師貪腐出逃美國,兩年未歸,可憐了我。拿了小米和美團的offer,要被延期,offer失效,工作重新找。把準備過程紀錄下來,共勉。

二叉樹的基礎 結點定義
public class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val){
        this.val = val;
    }
}
二叉樹的遍歷 前序遍歷

前序遍歷,遞歸法

public static void preorderTraversalRec(TreeNode root) {
    if(root == null){
        return;
    }

    System.out.print(root.val + " ");
    preorderTraversalRec(root.left);
    preorderTraversalRec(root.right);
}

前序遍歷,迭代法
思路:借助一個棧

public static void preorderTraversal(TreeNode root) {
    if(null == root){
        return;
    }

    Stack stack = new Stack<>();
    stack.push(root);

    while(!stack.empty()){
        TreeNode cur = stack.pop();

        System.out.println(cur.val);

        //后入先出,因而先壓右結點,再壓左結點
        if(null != cur.right){
            stack.push(cur.right);
        }

        if(null != cur.left){
            stack.push(cur.left);
        }

    }
}

中序遍歷

中序遍歷,遞歸法

public static void inorderTraversalRec(TreeNode root) {
    if(null == root){
        return;
    }

    inorderTraversalRec(root.left);
    System.out.print(root.val + " ");
    inorderTraversalRec(root.right);

}

中序遍歷,迭代法

public static void inorderTraversal(TreeNode root) {
    if(null == root){
        return;
    }

    Stack stack = new Stack<>();
    TreeNode cur = root;

    while(true){
        while(cur != null){
            stack.push(cur);
            cur = cur.left;
        }

        if(stack.empty()){
            break;
        }

        cur = stack.pop();
        System.out.print(cur.val + " ");
        cur = cur.right;
    }

}

后序遍歷

后序遍歷,遞歸法

public static void postorderTraversalRec(TreeNode root) {
    if(null == root){
        return;
    }

    postorderTraversalRec(root.left);
    postorderTraversalRec(root.right);
    System.out.print(root.val + " ");
}

后序遍歷,迭代法

public static void postorderTraversal(TreeNode root){
    if(null == root){
        return;
    }

    Stack s = new Stack();
    Stack output = new Stack<>();

    s.push(root);
    while(!s.empty()){
        TreeNode cur = s.pop();
        output.push(cur);

        if(cur.left != null){
            s.push(cur.left);
        }

        if(cur.right != null){
            s.push(cur.right);
        }
    }

    while(!output.empty()){
        System.out.print(output.pop().val + " ");
    }
}

分層遍歷

public static void levelTraversal(TreeNode root) {
    if(null == root){
        return;
    }

    Queue queue = new LinkedList<>();
    queue.push(root);

    while(!queue.empty()){
        TreeNode cur = queue.removeFirst();
        System.out.print(cur.val + " ");

        if(cur.left != null){
            queue.add(cur.left);
        }

        if(cur.right != null){
            queue.add(cur.right);
        }
    }
}

求二叉樹結點的個數(shù)

遞歸解法 時間復雜度O(n)

public static int getNodeNumRec(TreeNode root){
    if(null != root){
        return 0;
    }

    return getNodeNumRec(root.left) + getNodeNumRec(root.right) + 1;
}

迭代解法 時間復雜度O(n)
思路:與層級遍歷相同,遍歷的過程中紀錄結點數(shù)

public static int getNodeNum(TreeNode root){
    if(null != root){
        return 0;
    }

    int count = 1;
    Queue queue = LinkedList<>();
    queue.add(root);

    while(!queue.empty()){
        TreeNode cur = queue.remove();

        if(cur.left != null){
            queue.add(cur.left);
            count++;
        }

        if(cur.right != null){
            queue.add(cur.right);
            count++;
        }
    }

    return count;
}

求二叉樹的深度(高度)

遞歸解法 時間復雜度O(n)

public static int getDepthRec(TreeNode root) {
    if(null != root){
        return 0;
    }

    int leftDepth = getDepthRec(root.left);
    int rightDepth = getDepthRec(root.right);
    return Math.max(leftDepth, rightDepth) + 1;
}

迭代解法 時間復雜度O(n)

public static int getDepth(TreeNode root){
    if(null != root){
        return 0;
    }

    int depth = 0;
    int curLevelNodes = 1;
    int nextLevelNodes = 0;

    Queue queue = new LinkedList<>();
    queue.add(root);

    while(!queue.empty()){
        TreeNode cur = queue.remove();
        curLevelNodes--;

        if(cur.left != null){
            nextLevelNodes++;
            queue.add(cur.left);
        }

        if(cur.right != null){
            nextLevelNodes++;
            queue.add(cur.right);
        }

        if(curLevelNodes == 0){
            depth++;
            curLevelNodes = nextLevelNodes;
            nextLevelNodes = 0;
        }
    }

    return depth;
}

求二叉樹第K層的節(jié)點個數(shù)

遞歸解法
思路:求以root為根的k層節(jié)點數(shù)目 等價于 求以root左孩子為根的k-1層(因為少了root那一層)節(jié)點數(shù)目 加上 以root右孩子為根的k-1層(因為少了root那一層)節(jié)點數(shù)目

public static int getNodeNumKthLevelRec(TreeNode root, int k) {
    if(null != root || k < 0){
        return 0;
    }

    if(k == 1){
        return 1;
    }

    int leftNodeNumKth = getNodeNumKthLevelRec(root.left, k - 1);
    int rightNodeNumKth = getNodeNumKthLevelRec(root.right, k - 1);
    return leftNodeNumKth + rightNodeNumKth;
}

迭代法
思路:與求解樹深度的解法相同,需要

public static int getNodeNumKthLevel(TreeNode root, int k){
    if(root == null || k < 0){
        return 0;
    }

    Queue queue = new LinkedList<>();
    queue.add(root);

    int curLevelNodes = 1;
    int nextLevelNodes = 0;

    while(!queue.empty && k > 0){
        TreeNode cur = queue.remove();
        curLevelNodes--;

        if(cur.left != null){
            queue.add(cur.left);
            nextLevelNodes++;
        }

        if(cur.right != null){
            queue.add(cur.right);
            nextLevelNodes++;
        }

        if(curLevelNodes == 0){
            curLevelNodes = nextLevelNodes;
            nextLevelNodes = 0;
            k--;
        }
    }

    return curLevelNodes;
}

求二叉樹中葉子節(jié)點的個數(shù)

迭代法

public static int getNodeNumLeaf(TreeNode root) {
    if(root == null){
        return 0;
    }

    Queue queue = new LinkedList<>();
    queue.add(root);

    int leafNodeNum = 0;

    while(!queue.empty()){
        TreeNode cur = queue.remove();

        if(cur.left != null){
            queue.add(cur.left);
        }

        if(cur.right != null){
            queue.add(cur.right);
        }

        if(cur.left == null && cur.right = null){
            leafNodeNum++;
        }
    }
    return leafNodeNum;
}

兩個二叉樹之間的關系 判斷兩棵二叉樹是否相同的樹。

遞歸法

public static boolean isSameRec(TreeNode r1, TreeNode r2) {
    if(r1 == null && r2 == null){
        return true;
    }

    if(r1 == null || r2 == null){
        return false;
    }

    if(r1.val != r2.val){
        return false;
    }

    boolean leftRes = isSameRec(r1.left, r2.left);
    boolean rightRes = isSameRec(r1.right, r2.right);

    return leftRes && rightRes;
}

迭代法
思路:遍歷一遍,比對即可

public static boolean isSame(TreeNode r1, TreeNode r2) {
    if(r1 == null && r2 == null){
        return true;
    }

    if(r1 == null || r2 == null){
        return false;
    }

    Stack s1 = new Stack<>();
    Stack s2 = new Stack<>();

    s1.push(r1);
    s2.push(r2);

    while(!s1.empty() && !s2.empty()){
        TreeNode n1 = s1.pop();
        TreeNode n2 = s2.pop();

        if(n1 == null && n2 == null){
            continue;
        }else if(n1 != null && n2 != null && n1.val == n2.val){
            s1.push(n1.right);
            s1.push(n1.left);
            s2.push(n2.right);
            s2.push(n2.left);
        }else{
            return false;
        }
    }
    return true;
 }

判斷二叉樹是不是平衡二叉樹

遞歸解法

思路:
(1)如果二叉樹為空,返回真
(2)如果二叉樹不為空,如果左子樹和右子樹都是AVL樹并且左子樹和右子樹高度相差不大于1,返回真,其他返回假
public static boolean isAVLRec(TreeNode root) {
    if(root == null){
        return true;
    }

    if(Math.abs(getDepthRec(root.left) - getDepthRec(root.right)) > 1){
        return false;
    }

    return isAVLRec(root.left) && isAVLRec(root.right);
}

樹的鏡像 判斷兩個樹是否互相鏡像
    public static boolean isMirrorRec(TreeNode r1, TreeNode r2){
   if(r1 == null && r2 == null){
       return true;
   }

   if(r1 == null || r2 == null){
       return false;
   }

   if(r1.val != r2.val){
       return false;
   }

   return isMirrorRec(r1.left, r2.right) && isMirrorRec(r1.right, r2.left);
    }
求樹的鏡像

遞歸解法
(1)如果二叉樹為空,返回空
(2)如果二叉樹不為空,求左子樹和右子樹的鏡像,然后交換左子樹和右子樹

破壞原來的樹

public static TreeNode mirrorRec(TreeNode root) {
if(root == null){
   return null;
}

TreeNode left = mirrorRec(root.left);
TreeNode right = mirrorRec(root.right);

root.left = right;
root.right = left;
return root;
}

2.保存原來的樹

public static TreeNode mirrorCopyRec(TreeNode root) {
    if(root == null){
        return null;
    }

    TreeNode newRoot = new TreeNode(root.val);
    newRoot.left = mirrorCopyRec(root.right);
    newRoot.right = mirrorCopyRec(root.left);

    return newRoot;

}

迭代解法

破壞原來的樹

public static void mirror(TreeNode root) {
    if(root == null){
        return;
    }

    Stack stack = new Stack();
    stack.push(root);

    while(!stack.empty()){
        TreeNode cur = stack.pop();

        TreeNode tmp = cur.left;
        cur.left = cur.right;
        cur.right = tmp;

        if(cur.left != null){
            stack.push(cur.left);
        }

        if(cur.right != null){
            stack.push(cur.right);
        }
    }
}

不能破壞原來的樹,返回一個新的鏡像樹

public static TreeNode mirrorCopy(TreeNode root){
    if(root == null){
        return null;
    }

    Stack stack = new Stack<>();
    Stack newStack = new Stack<>();
    stack.push(root);
    TreeNode newRoot = new TreeNode(root.val);
    newStack.push(newRoot);

    while(!stack.empty()){
        TreeNode cur = stack.pop();
        TreeNode newCur = newStack.pop();

        if(cur.left != null){
            stack.push(cur.left);
            newCur.right = new TreeNode(cur.left.val);
            newStack.push(newCur.right);
        }

        if(cur.right != null){
            stack.push(cur.right);
            newCur.left = new TreeNode(cur.right.val);
            newStack.push(newCur.left);
        }
    }
    return newRoot;
}

求二叉樹中兩個節(jié)點的最低公共祖先節(jié)點

遞歸法
思路:1. 如果其中一個結點為根結點,則返回根結點

如果一個左子樹找到,一個在右子樹找到,則說明root是唯一可能的最低公共祖先

其他情況是要不然在左子樹要不然在右子樹

public static TreeNode getLastCommonParentRec(TreeNode root, TreeNode n1, TreeNode n2) {
    if (root == null || n1 == null || n2 == null) {
        return null;
    }

    if(root.equals(n1) || root.equals(n2)){
        return root;
    }

    TreeNode commonInLeft = getLastCommonParentRec(root.left, n1, n2);
    TreeNode commonInRight = getLastCommonParentRec(root.right, n1, n2);
    if(commonInLeft != null && commonInRight != null){
        return root;
    }

    if(commonInLeft == null){
        return commonInRight;
    }

    if(commonInRight == null){
        return commonInLeft;
    }
    return root;
}

迭代法

public static TreeNode getLastCommonParent(TreeNode root, TreeNode n1, TreeNode n2){
    if(root == null || n1 == null || n2 == null){
        return null;
    }

    List list1= new ArrayList<>();
    List list2 = new ArrayList<>();

    boolean res1 = getNodePath(root, n1, list1);
    boolean res2 = getNodePath(root, n2, list2);

    if(!res1 || !res2){
        return null;
    }

    Iterator iter1 = list1.iterator();
    Iterator iter2 = list2.iterator();
    TreeNode last = null;

    while(iter1.hasNext() && iter2.hasNext()){
        TreeNode tmp1 = iter1.next();
        TreeNode tmp2 = iter2.next();

        if(tmp1 == tmp2){
            last = tmp1;
        }else{
            break;
        }
    }
    return last;
}

private static boolean getNodePath(TreeNode root, TreeNode n, List path){
    if(root == null){
        return false;
    }

    path.add(root);
    if(root == n){
        return true;
    }

    boolean found = false;
    found = getNodePath(root.left, n, path);

    if(!found){
        found = getNodePath(root.right, n, path);
    }

    if(!found){
        path.remove(root);
    }

    return found;
}

本章參考http://blog.csdn.net/fightfor...

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70112.html

相關文章

  • 前端該如何準備數(shù)據(jù)結構和算法?

    摘要:很多前端同學在看到數(shù)據(jù)結構和算法后會有一定的抵觸心理,或者嘗試去練習,但是被難倒,從而放棄。本文選擇的數(shù)據(jù)結構和算法的類別均是出現(xiàn)頻率最高,以及應用最廣的類別。面試這是非常現(xiàn)實的一點,也是很多前端學習數(shù)據(jù)結構和算法的原因。 一、導讀 據(jù)我了解,前端程序員有相當一部分對數(shù)據(jù)結構和算法的基礎概念都不是很清晰,這直接導致很多人在看到有關這部分的內容就會望而卻步。 實際上,當你了解了數(shù)據(jù)結構和...

    simon_chen 評論0 收藏0
  • 使用JavaScript完成叉樹的一些基本操作

    摘要:另外,由于篇幅有限,本篇的重點在于二叉樹的常見算法以及實現(xiàn)。常見的二叉樹實現(xiàn)代碼之前寫過相關的文章,是關于如何創(chuàng)建及遍歷二叉樹的,這里不再贅述。同時我們注意到,在二叉樹深度比較大的時候,我們光是比較左右是不夠的。 本篇為復習過程中遇到過的總結,同時也給準備面試的同學一份參考。另外,由于篇幅有限,本篇的重點在于二叉樹的常見算法以及實現(xiàn)。 常見的二叉樹實現(xiàn)代碼 之前寫過相關的文章,是關于如...

    YPHP 評論0 收藏0
  • LeetCode 攻略 - 2019 年 7 月下半月匯總(100 題攻略)

    摘要:月下半旬攻略道題,目前已攻略題。目前簡單難度攻略已經(jīng)到題,所以后面會調整自己,在刷算法與數(shù)據(jù)結構的同時,攻略中等難度的題目。 Create by jsliang on 2019-07-30 16:15:37 Recently revised in 2019-07-30 17:04:20 7 月下半旬攻略 45 道題,目前已攻略 100 題。 一 目錄 不折騰的前端,和咸魚有什么區(qū)別...

    tain335 評論0 收藏0
  • 準備下次編程面試前你應該知道的數(shù)據(jù)結構

    摘要:以下內容編譯自他的這篇準備下次編程面試前你應該知道的數(shù)據(jù)結構瑞典計算機科學家在年寫了一本書,叫作算法數(shù)據(jù)結構程序。 國外 IT 教育學院 Educative.io 創(chuàng)始人 Fahim ul Haq 寫過一篇過萬贊的文章《The top data structures you should know for your next coding interview》,總結了程序員面試中需要掌...

    desdik 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<