剑指offer之56-60题解

剑指offer之56-60题解


目录

  1. 删除链表中重复的结点
  2. 二叉树的下一个结点
  3. 对称的二叉树
  4. 按之字型顺序打印二叉树
  5. 把二叉树打印成多行

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

(一)题目描述

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

(二)思路

  1. 首先添加一个头节点,以方便碰到第一个,第二个节点就相同的情况

  2. 设置 pre ,last 指针, pre指针指向当前确定不重复的那个节点,而last指针相当于工作指针,一直往后面搜索。

(三)代码实现

  1. 递归版本
public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        if (pHead==null||pHead.next==null)
            return pHead;
        ListNode next = pHead.next;
        if (pHead.val==next.val){
            while (next!=null&&pHead.val==next.val)
                next = next.next;
            return deleteDuplication(next);
        }else {
            pHead.next = deleteDuplication(pHead.next);
            return pHead;
        }
    }
}
  1. 非递归版本
public class Solution {
   public ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null || pHead.next == null)
            return pHead;
        ListNode Head = new ListNode(0);
        Head.next = pHead;
        ListNode pre = Head;
        ListNode last = Head.next;
        while (last != null) {
            if (last.next != null && last.val == last.next.val) {
                while (last.next != null && last.val == last.next.val) 
                    last = last.next;
                pre.next = last.next;
                last = last.next;
            } else {
                pre = pre.next;
                last = last.next;
            }
        }
        return Head.next;
    }
}

57. 二叉树的下一个结点

(一)题目描述

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

(二)思路

  1. 如果节点有右子树,那么右子树的最左节点就是下一个节点
  2. 如果没右子树,则找到第一个当前节点是父节点左孩子的节点。
  3. 如果遇到了根节点仍没有找到,那么返回null。
  4. 可以参考 https://blog.csdn.net/weixin_41910694/article/details/94294812,思路是一样的

(三)代码实现

public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode) {
        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){
            if (pNode.next.left == pNode)
                return pNode.next;
            pNode = pNode.next;
        }
        return null;
    }
}

58. 对称的二叉树

(一)题目描述

在这里插入图片描述
(二)思路

  1. 判断两个节点是否相同,相同继续遍历它的左右节点。

(三)代码实现

public class Solution {
    boolean isSymmetrical(TreeNode pRoot) {
        if (pRoot == null)
            return true;
        return isSymmetrical(pRoot.left, pRoot.right);
    }

    boolean isSymmetrical(TreeNode t1, TreeNode t2) {
        if (t1 == null && t2 == null)
            return true;
        if (t1 == null || t2 == null)
            return false;
        if (t1.val != t2.val)
            return false;
        return isSymmetrical(t1.left, t2.right) && isSymmetrical(t1.right, t2.left);
    }
}

59. 按之字型顺序打印二叉树

(一)题目描述

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

(二)思路

  1. 创建变量reverse控制打印方向。
  2. 如果为false从左打印,如果为true从右到左打印。

(三)代码实现

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(pRoot);
        boolean reverse = false;
        while (!queue.isEmpty()) {
            ArrayList<Integer> list = new ArrayList<>();
            int cnt = queue.size();
            while (cnt-- > 0) {
                TreeNode node = queue.poll();
                if (node == null)
                    continue;
                list.add(node.val);
                queue.offer(node.left);
                queue.offer(node.right);
            }
            if (reverse)
                Collections.reverse(list);
            reverse = !reverse;
            if (list.size() != 0)
                ret.add(list);
        }
        return ret;
    }
}

60. 把二叉树打印成多行

(一)题目描述

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

(二)思路

  1. 可以看成上一题的简化版。

(三)代码实现

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
    ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(pRoot);
        while (!queue.isEmpty()) {
            ArrayList<Integer> list = new ArrayList<>();
            int cnt = queue.size();
            while (cnt-- > 0) {
                TreeNode node = queue.poll();
                if (node == null)
                    continue;
                list.add(node.val);
                queue.offer(node.left);
                queue.offer(node.right);
            }
            if (!list.isEmpty())
                ret.add(list);
        }
        return ret;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值