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.镜像二叉树
题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
思路:
递归:
- 只需要pRoot.left和pRoot.right是否对称即可
- 左右节点的值相等且对称子树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);
}
}