[Java]剑指offer56-60题_day12

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

题目描述

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

思路一:递归

package com.matajie;

/**
 * 56.删除链表中重复的节点
 *
 * 题目描述
 * 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,
 * 重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
 *
 * 我的程序才不会有bug!
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class DeleteDuplication {
    public class ListNode {
        int val;
        ListNode next = null;

        ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode deleteDuplication(ListNode pHead)
    {
         if(pHead == null||pHead.next == null){
             return pHead;
         }
         if(pHead.val == pHead.next.val){
             ListNode next = pHead.next;
             while (next != null && next.val == pHead.val) {
                 next = next.next;
             }
                 return deleteDuplication(next);
         }else {
             pHead.next = deleteDuplication(pHead.next);
         }
             return pHead;
    }
}

思路二:

新建一个头节点

package com.matajie;

/**
 * 56.删除链表中重复的节点
 *
 * 题目描述
 * 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,
 * 重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
 *
 * 我的程序才不会有bug!
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class DeleteDuplication {
    public class ListNode {
        int val;
        ListNode next = null;

        ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode deleteDuplication(ListNode pHead)
    {
        ListNode first = new ListNode(-1);//设置一个头节点
        first.next = pHead;
        ListNode p = pHead;
        ListNode last = first;
        while (p != null && p.next != null){
            if(p.val == p.next.val){
                int val = p.val;
                while (p != null && p.val == val){
                    p = p.next;
                    last.next = p;
                }
            }else {
                last = p;
                p = p.next;
            }
        }
        return first.next;
    }
}

57.二叉树的下一个节点

题目描述

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

思路:

在这里插入图片描述
如图,有右子树的,那么下一个节点就是右子数字左边的点(D,B,E,A,C,G)
没有右子树,则找第一个当前节点是父节点左孩子的节点(N,I,L,H,J,K,M)

package com.matajie;

/**
 * 57.二叉树的下一个节点
 * 题目描述
 *
 * 给定一个二叉树和其中的一个结点,
 * 请找出中序遍历顺序的下一个结点并且返回。
 * 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
 *
 * 我的程序才不会有bug!
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class GetNext {
    public class TreeLinkNode {
        int val;
        TreeLinkNode left = null;
        TreeLinkNode right = null;
        TreeLinkNode next = null;

        TreeLinkNode(int val) {
            this.val = val;
        }
    }
    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;//退到了根节点仍没找到,则返回null
    }
}

58.镜像二叉树

题目描述

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

思路:

递归:

  1. 只需要pRoot.left和pRoot.right是否对称即可
  2. 左右节点的值相等且对称子树left.right,right.right left.right,right.right也对称
package com.matajie;

/**
 * 58.镜像二叉树
 * 题目描述
 *
 * 请实现一个函数,用来判断一颗二叉树是不是对称的。
 * 注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
 *
 * 我的程序才不会有bug!
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class IsSymmetrical {
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int val) {
            this.val = val;

        }

    }
    boolean isSymmetrical(TreeNode pRoot)
    {
           if(pRoot == null) return true;
           return isSymmetrical2(pRoot.left,pRoot.right);
    }
    private boolean isSymmetrical2(TreeNode left,TreeNode right){
        if(left == null && right == null) return true;
        if(left == null || right == null) return false;
        return left.val == right.val //为镜像的条件,左右节点值相等
        &&isSymmetrical2(left.left,right.right)//对称的子树也是镜像
        &&isSymmetrical2(left.right,right.left);
    }
}

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

题目描述

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

package com.matajie;

import java.util.ArrayList;
import java.util.Stack;

/**
 * 59.
 *
 * 我的程序才不会有bug!
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class Print {
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int val) {
            this.val = val;

        }

    }
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
          int layer = 1;
        Stack<TreeNode> s1 = new Stack<>();//s1存奇数层节点
        s1.push(pRoot);
        Stack<TreeNode> s2 = new Stack<>();//s2存偶数层节点
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        while (!s1.empty() || !s2.empty()){
            if(layer % 2 != 0){
                ArrayList<Integer> temp = new ArrayList<>();
                while (!s1.empty()){
                    TreeNode node = s1.pop();
                    if(node != null){
                        temp.add(node.val);
                        s2.push(node.left);
                        s2.push(node.right);
                    }
                }
                if(!temp.isEmpty()){
                    list.add(temp);
                    layer++;
                }
            }else {
                ArrayList<Integer> temp = new ArrayList<>();
                while (!s2.empty()){
                    TreeNode node = s2.pop();
                    if(node != null){
                        temp.add(node.val);
                        s1.push(node.right);
                        s1.push(node.left);
                    }
                }
                if(!temp.isEmpty()){
                    list.add(temp);
                    layer++;
                }
            }
        }
        return list;
    }
}

60.把二叉树打印成多行

题目描述

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

思路一:

按之字形打印用两个栈,按顺序打印用两个队列

package com.matajie;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 我的程序才不会有bug!
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class Print2 {
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int val) {
            this.val = val;

        }

    }
    ArrayList<ArrayList<Integer>> Print2(TreeNode pRoot) {
     ArrayList<ArrayList<Integer>> result = new ArrayList<>();
     if(pRoot == null)
         return result;
        Queue<TreeNode> layer = new LinkedList<>();
        ArrayList<Integer> layerList = new ArrayList<>();
        layer.add(pRoot);
        int start = 0;
        int end = 1;
        while (!layer.isEmpty()){
            TreeNode cur = layer.remove();
            layerList.add(cur.val);
            start++;
            if(cur.left != null){
                layer.add(cur.left);
            }
            if(cur.right != null){
                layer.add(cur.right);
            }
            if(start == end){
                end = layer.size();
                start = 0;
                result.add(layerList);
                layerList = new ArrayList<>();
            }
        }
        return result;
    }

}

思路二:递归

package com.matajie;

import java.util.ArrayList;
/**
 * 我的程序才不会有bug!
 * author:年仅18岁的天才少年程序员丶mata杰
 **/
public class Print2 {
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int val) {
            this.val = val;

        }

    }
    ArrayList<ArrayList<Integer>> Print2(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        depth(pRoot,1,list);
        return list;
    }
    private void depth(TreeNode root,int depth,ArrayList<ArrayList<Integer>> list){
        if(root == null) return;
        if(depth > list.size())
            list.add(new ArrayList<>());
        list.get(depth-1).add(root.val);
        depth(root.left,depth+1,list);
        depth(root.right,depth+1,list);
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值