您的位置:首页 > Web前端 > JavaScript

11天刷剑指offer——JavaScript版——第十天

2019-03-06 11:32 183 查看

文章目录

  • 56、删除链表中重复的结点
  • 57、二叉树的下一个结点
  • 58、对称二叉树
  • 59、按之字形顺序打印二叉树
  • 60、把二叉树打印成多行
  • 55、链表中环的入口结点

    题目描述

    一个链表中包含环,请找出该链表的环的入口结点。

    思路

    通过map来存储每次访问的结点,如果有重复,则是链表入口结点。

    代码

    function EntryNodeOfLoop(pHead)
    {
    // write code here
    var cur = pHead,prev,obj={},lt;
    while(cur != null){
    lt = cur.val;//头结点的值
    if(!obj[lt]){
    obj[lt] = 1;
    cur = cur.next;//节点值不重复就跳到next
    }else{
    return cur;
    }
    }
    }

    56、删除链表中重复的结点

    题目描述

    在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

    思路

    需要三个指针,第一个指针first的next指向头结点,第二个指针pre指向first,确保每次指向的是重复结点的前一个结点,第三个指针head来遍历,遇到重复结点,则向后,直到找到当前结点不等于下一个结点时,将pre的next指向head。

    代码

    function deleteDuplication(pHead)
    {
    // write code here
    if(pHead==null||pHead.next==null) return pHead;// 只有0个或1个结点,则返回
    var first={
    val:0,
    next:pHead
    }
    var head=pHead,pre=first;
    while(head!=null&&head.next!=null){  //保证头指针不为空,继续往下
    if(head.val==head.next.val){  //判断前后指针值如果一样,当前节点是重复节点
    while(head.next&&head.next.val==head.val){
    // 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
    head=head.next;   //头指针往后移,遍历
    }
    pre.next=head.next; //指针赋值,就相当于删除
    }else{  //前后指针值不一样,当前节点不是重复节点
    //如果当前节点和下一个节点值不等,则向后移动一位
    pre.next=head;
    pre=pre.next;
    }
    //pre=head;
    head=head.next;//跳到下一个节点
    
    }
    return first.next;
    }

    57、二叉树的下一个结点

    题目描述

    给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。(有一个树节点,找出他中序遍历输出的下一个节点)

    思路

    1. 二叉树为空,则返回空;
    2. 节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点;
      (若该节点存在右子树:则下一个节点为右子树最左子节点)
    3. 节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。

    代码

    function GetNext(pNode)
    {
    // write code here
    if(pNode==null) return null; //二叉树为空,则返回空
    if(pNode.right!=null) {//节点右孩子存在情况
    pNode=pNode.right;
    while(pNode.left!=null){//沿着向左节点找到叶子节点
    pNode=pNode.left;
    }
    return pNode;
    }
    while(pNode.next!=null){ //节点没有右子树
    var pRoot=pNode.next;
    if(pRoot.left==pNode){
    return pRoot  //该节点为父节点的左子节点,则下一个节点为其父节点,返回父节点
    }
    //该节点为父节点的右子节点,则沿着父节点向上遍历,直到找到一个节点的父节点的左子节点为该节点,则该节点的父节点下一个节点
    pNode=pNode.next;
    }
    return null
    
    }

    58、对称二叉树

    题目描述

    请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

    思路

    采用递归方法,先判断根节点的左子树和右子树是否为空,同时为空,则返回true,一个为空,则为false。同时不为空,则判断其值是否相等,然后递归判断左子树和右子树的

    代码

    function isSymmetrical(pRoot)
    {
    // write code here
    return isSymmetricalCore(pRoot,pRoot);
    function isSymmetricalCore(left,right){
    if(left==null&&right==null) return true; //判断根节点的左子树和右子树是否为空,同时为空,则返回true
    if(left==null||right==null) return false;  //其中一棵树为空,就返回空
    if(left.val!=right.val) return false;
    return isSymmetricalCore(left.left,right.right)&&isSymmetricalCore(left.right,right.left)
    }
    
    }

    59、按之字形顺序打印二叉树

    题目描述

    请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

    思路

    按深度遍历二叉树,深度(从0开始)为奇数的反转加入数组。

    代码

    function Print(pRoot)
    {
    // write code here
    var queue = [];//存储节点队列
    var result = [];  //存储打印顺序数组
    if(pRoot==null) return result; //树为空,直接返回
    var nextLevel = 0;
    queue.push(pRoot);  //队列实现先进先出
    var toBePrinted = 1;//每一行节点个数
    var level = 0;//深度
    var arr = [];
    while(queue.length){
    //shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
    var temp = queue.shift();
    toBePrinted--;
    arr.push(temp.val); //将树的值放置arr数组
    if(temp.left){//左子树不为空
    queue.push(temp.left);
    nextLevel++;
    }
    if(temp.right){//右子树不为空
    queue.push(temp.right);
    nextLevel++;
    }
    if(toBePrinted==0){
    toBePrinted=nextLevel;//记录下一层需要输出数的个数
    nextLevel=0; //复位
    level++;  //深度增加
    if(level%2==0){ //偶数层反转
    arr.reverse();
    }
    result.push(arr);
    arr = [];
    }
    }
    return result;
    }

    60、把二叉树打印成多行

    题目描述

    从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

    思路

    采用队列数据结构,同时需要两个变量分别存储这一层和下一层结点个数。当前层#### 代码结点个数为零时,则输出结点

    代码

    function Print(pRoot)
    {
    // write code here
    var queue = [];//存储节点队列
    var result = []; //存储打印顺序数组
    if(pRoot==null) return result;
    var nextLevel = 0;
    queue.push(pRoot);
    var toBePrinted = 1;//每一行节点个数
    var arr = [];
    while(queue.length){
    //shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
    var temp = queue.shift();
    toBePrinted--;
    arr.push(temp.val);
    if(temp.left){
    queue.push(temp.left);
    nextLevel++;
    }
    if(temp.right){
    queue.push(temp.right);
    nextLevel++;
    }
    if(toBePrinted==0){
    toBePrinted=nextLevel;
    nextLevel=0;
    result.push(arr);
    arr = [];
    }
    }
    return result;
    
    }
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: