删除链表中的重复结点
题目描述:
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表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 head = new ListNode(0);
head.next = pHead;
ListNode p = head;
ListNode q = head.next;
while (q!=null){
if(q.next!=null && q.val == q.next.val){
while (q.next!=null && q.val == q.next.val){
q = q.next;
}
p.next = q.next;
q = q.next;
}else{
p = p.next;
q = q.next;
}
}
return head.next;
}
}
二叉树的下一个结点
题目描述:
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路分析:
分三种情况讨论:
- 二叉树为空,则返回空;
- 节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点;
- 节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。
算法实现:
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;
}
}
对称的二叉树
题目描述:
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
思路分析:
采用递归的方法。定义一个函数比较:
- 左子树的左子树和右子树的右子树是否相同
- 左子树的右子树和右子树的左子树是否相同
算法实现:
public class Solution {
boolean isSymmetrical(TreeNode pRoot)
{
if(pRoot == null)
return true;
return comRoot(pRoot.left,pRoot.right);
}
private boolean comRoot(TreeNode left,TreeNode right){
if(left == null)
return right == null;
if(right == null)
return false;
if(left.val == right.val)
return comRoot(left.left,right.right) && comRoot(left.right,right.left);
return false;
}
}
按之字形顺序打印二叉树
题目描述:
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路分析:
定义一个队列用来保存每层的节点,并把根节点添加进队列中进行初始化,当队列不为空时,逐个出队列中的元素,并把这个元素加到列表中,再把它的左结点和右结点添加进队列中,注意:在使用队列来进行层次遍历。不需要使用两个队列分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。要想实现之字形打印可以定义一个boolean变量,每打印一行就对该变量进行取反即可。
算法实现:
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.add(pRoot);
boolean reverse = false;
while(!queue.isEmpty()){
ArrayList<Integer> eachDepth = new ArrayList<>();
int count = queue.size();
while(count > 0){
count --;
TreeNode node = queue.poll();
if(node == null)
continue;
eachDepth.add(node.val);
queue.add(node.left);
queue.add(node.right);
}
if(reverse)
Collections.reverse(eachDepth);
reverse = !reverse;
if(eachDepth.size() != 0)
list.add(eachDepth);
}
return list;
}
}
把二叉树打印成多行
题目描述:
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
思路分析:
- 非递归方法,思路同上。
- 用递归的方法,方法中传递一个当前结点所在层次就可以用前序遍历实现了。
算法实现:
非递归方法:
public class Solution {
ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if(pRoot != null)
queue.add(pRoot);
int num = 1;
while(!queue.isEmpty()){
ArrayList<Integer> eachDepth = new ArrayList<>();
int temp = 0;
while(num > 0){
num --;
TreeNode node = queue.poll();
eachDepth.add(node.val);
if(node.left != null){
temp ++;
queue.add(node.left);
}
if(node.right != null){
temp ++;
queue.add(node.right);
}
}
num = temp;
list.add(eachDepth);
}
return list;
}
}
递归实现:
public class Solution {
ArrayList<ArrayList<Integer> > Print(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<Integer>());
list.get(depth-1).add(root.val);
depth(root.left,depth+1,list);
depth(root.right,depth+1,list);
}
}