剑指Offer行榜【牛客网】练习(十三)

28 篇文章 0 订阅
13 篇文章 0 订阅
1、删除链表中的重复结点

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

思路:
遍历一次得到重复结点,然后再遍历一次删除多余结点。

代码:

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class Solution {
    public ListNode deleteDuplication(ListNode pHead)
    {
        if(pHead==null||pHead.next==null){
            return pHead;
        }
        ArrayList<Integer> vals = new ArrayList<>();
        Set<Integer> dupVals = new HashSet<>();
        ListNode pointer1 = pHead;
        while(pointer1!=null){
            if(vals.indexOf(pointer1.val)>=0){
                dupVals.add(pointer1.val);
            }
            vals.add(pointer1.val);
            pointer1 = pointer1.next;
        }
        while(pHead!=null&&dupVals.contains(pHead.val)){
            pHead = pHead.next;
        }
        ListNode pointer2 = pHead;
        while(pointer2!=null&&pointer2.next!=null){
            if(dupVals.contains(pointer2.next.val)){
                pointer2.next = pointer2.next.next;
            }else{
                pointer2 = pointer2.next;
            }
        }
        return pHead;
    }
}
2、二叉树的下一个结点

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

思路:
分三种情况:
1、结点==null,返回null
2、结点有右子结点。找到右子结点的最左子结点,返回这个结点
3、结点没有右子结点。它是父节点的左子结点,返回父结点;它是父节点的右子结点,追溯父节点,直到父节点是祖父结点的左子结点,返回祖父结点。

代码:

/*
public class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if(pNode==null){
            return null;
        }
        if(pNode.right!=null){
            TreeLinkNode nextNode = pNode.right;
            while(nextNode.left!=null){
                nextNode = nextNode.left;
            }
            return nextNode;
        }else{
            while(pNode.next!=null){
                if(pNode.next.left==pNode){
                    return pNode.next;
                }else{
                    pNode = pNode.next;
                }
            }
            return null;
        }
    }
}
3、对称的二叉树

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

思路:
利用递归
当 leftNode的左结点=rightNode的右结点 && leftNode的右结点=rightNode的左结点【此处的=可以都为null,可以数值相等】
递归判断leftNode.left?=rightNode.right && leftNode.right?=rightNode.left

代码:

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    boolean isSymmetrical(TreeNode pRoot)
    {
        if(pRoot==null){
            return true;
        }
        if(pRoot.left==null&&pRoot.right==null){
            return true;
        }else if(pRoot.left==null||pRoot.right==null){
            return false;
        }else{
            if(pRoot.left.val!=pRoot.right.val){
                return false;
            }else{
                return judgeSymmetrical(pRoot.left,pRoot.right);
            }
        }
        
    }
    boolean judgeSymmetrical(TreeNode leftNode,TreeNode rightNode){
        if(leftNode==null&&rightNode==null){
            return true;
        }else if(leftNode==null||rightNode==null){
            return false;
        }else{
            if(isEqualNode(leftNode.left,rightNode.right)
              &&isEqualNode(leftNode.right,rightNode.left)){
                return judgeSymmetrical(leftNode.left,rightNode.right)
                    && judgeSymmetrical(leftNode.right,rightNode.left);
            }else{
                return false;
            }
        }
    }
    boolean isEqualNode(TreeNode node1,TreeNode node2){
        if(node1==null&&node2==null){
            return true;
        }else if(node1==null||node2==null){
            return false;
        }else{
            if(node1.val==node2.val){
                return true;
            }else{
                return false;
            }
        }
    }
}
4、按之字形打印二叉树

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

思路:
使用两个栈存储奇数层和偶数层的结点。
奇数层,取出奇数栈的结点,依次将值加入ArrayList中,并依次将左子结点和右子结点加入偶数栈。
偶数层,取出偶数栈的结点,依次将值加入ArrayList中,并依次将右子结点和左子结点加入奇数栈。

代码:

import java.util.ArrayList;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
import java.util.Stack;
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot){
        Stack<TreeNode> odd = new Stack<TreeNode>();
        Stack<TreeNode> even = new Stack<TreeNode>();
        odd.push(pRoot);
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        int layer = 1;
        while(!odd.empty()||!even.empty()){
            if(layer%2==1){
                ArrayList<Integer> temp = new ArrayList<>();
                while(!odd.empty()){
                    TreeNode node = odd.pop();
                    if(node!=null){
                        temp.add(node.val);
                        even.push(node.left);
                        even.push(node.right);
                    }
                }
                if(temp.size()>0){
                    list.add(temp);
                    layer++;
                }
            }else{
                ArrayList<Integer> temp = new ArrayList<>();
                while(!even.empty()){
                    TreeNode node = even.pop();
                    if(node!=null){
                        temp.add(node.val);
                        odd.push(node.right);
                        odd.push(node.left);
                    }
                }
                if(temp.size()>0){
                    list.add(temp);
                    layer++;
                }
            }
        }
        return list;
    }

}
5、把二叉树打印成多行

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

思路:
类似上一题,存两层ArrayList,依次取值,并依次将左子结点和右子结点加入另外一个list中。

代码:

import java.util.ArrayList;


/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        ArrayList<TreeNode> odd = new ArrayList<>();
        ArrayList<TreeNode> even = new ArrayList<>();
        odd.add(pRoot);
        int layer = 1;
        while(!odd.isEmpty()||!even.isEmpty()){
            ArrayList<Integer> temp = new ArrayList<>();
            if(layer%2==1){
                while(!odd.isEmpty()){
                    TreeNode node = odd.get(0);
                    odd.remove(0);
                    if(node!=null){
                        temp.add(node.val);
                        even.add(node.left);
                        even.add(node.right);
                    }
                }
            }else{
                while(!even.isEmpty()){
                    TreeNode node = even.get(0);
                    even.remove(0);
                    if(node!=null){
                        temp.add(node.val);
                        odd.add(node.left);
                        odd.add(node.right);
                    }
                }
            }
            if(temp.size()>0){
                list.add(temp);
                layer++;
            }
        }
        return list;
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值