剑指offer之56-60题解
目录
56. 删除链表中重复的结点
(一)题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
(二)思路
-
首先添加一个头节点,以方便碰到第一个,第二个节点就相同的情况
-
设置 pre ,last 指针, pre指针指向当前确定不重复的那个节点,而last指针相当于工作指针,一直往后面搜索。
(三)代码实现
- 递归版本
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;
}
}
}
- 非递归版本
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. 二叉树的下一个结点
(一)题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
(二)思路
- 如果节点有右子树,那么右子树的最左节点就是下一个节点
- 如果没右子树,则找到第一个当前节点是父节点左孩子的节点。
- 如果遇到了根节点仍没有找到,那么返回null。
- 可以参考 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. 对称的二叉树
(一)题目描述
(二)思路
- 判断两个节点是否相同,相同继续遍历它的左右节点。
(三)代码实现
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. 按之字型顺序打印二叉树
(一)题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
(二)思路
- 创建变量reverse控制打印方向。
- 如果为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. 把二叉树打印成多行
(一)题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
(二)思路
- 可以看成上一题的简化版。
(三)代码实现
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;
}
}