剑指offer题解6
22 二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
分析:
二叉搜索树的或许遍历的末尾的数一定是根节点,在根节点的前一部分分为两个连续的序列,一个是比根节点小的连续的序列(在树的结构中是在根节点的左侧),一个是比根节点大的连续的序列(在树的结构中是在根节点的右侧);必须满足这个条件,而这个问题可以拆分为相同的子问题
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence==null||sequence.length==0){
return false;
}
return help(sequence,0,sequence.length-1);
}
private boolean help(int[] array,int st,int end){
if(st>=end){
return true;
}
int i=st;
//跳过根节点小的数,找到第一个大于根节点的数
for(;i<end;i++){
if(array[i]>array[end]){
break;
}
}
//判断是否满足所有的数都比根节点
for(int j=i;j<end;j++){
if(array[j]<array[end]){
return false;
}
}
return help(array,st,i-1)&&help(array,i,end-1);
}
}
23 二叉树中和为某一值的路径
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
分析:
回溯法,遍历所有的路径即可,判断到达叶子节点时和是否为target
import java.util.ArrayList;
public class Solution {
ArrayList<ArrayList<Integer>> all=new ArrayList<>();
ArrayList<Integer> path=new ArrayList<>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
if(root==null){
return all;
}
//添加路径
path.add(root.val);
target-=root.val;
if(target==0&&root.left==null&&root.right==null){
all.add(new ArrayList(path));
}
FindPath(root.left,target);
FindPath(root.right,target);
//返回之前需要删除该节点
path.remove(path.size()-1);
return all;
}
}
24 复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
分析:
方法1,第一步:使用Map存储{原节点,现节点},第二步:将对应的next和random复制过去即可。
方法2:复制每个节点然后插入到当前节点的后面,然后从头遍历节点处理random,然后再遍历处理next,构成一个链表
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
import java.util.Map;
import java.util.HashMap;
public class Solution {
//map
public RandomListNode Clone(RandomListNode pHead)
{
RandomListNode head=pHead;
Map<RandomListNode,RandomListNode> map=new HashMap<>();
while(pHead!=null){
//构造每一个节点,不处理next和random
RandomListNode curr=new RandomListNode(pHead.label);
map.put(pHead,curr);
pHead=pHead.next;
}
pHead=head;
while(pHead!=null){
//map中存储着相对位置,处理next和random
map.get(pHead).next=map.get(pHead.next);
map.get(pHead).random=map.get(pHead.random);
pHead=pHead.next;
}
return map.get(head);
}
}
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead==null){
return null;
}
RandomListNode head=pHead;
//插入
while(pHead!=null){
RandomListNode newNode=new RandomListNode(pHead.label);
RandomListNode next=pHead.next;
pHead.next=newNode;
newNode.next=next;
pHead=next;
}
//处理random
pHead=head;
RandomListNode res=head.next;
while(pHead!=null){
pHead.next.random=pHead.random==null?null:pHead.random.next;
pHead=pHead.next.next;
}
//处理next
pHead=head;
while(pHead!=null){
RandomListNode newNode=pHead.next;
pHead.next=newNode.next;
newNode.next=newNode.next==null?null:newNode.next.next;
pHead=pHead.next;
}
return res;
}
}
25 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
分析:中序遍历即可
public class Solution {
TreeNode head=null;
TreeNode curr=null;
public TreeNode Convert(TreeNode root) {
if(root==null){
return null;
}
Convert(root.left);
if(head==null){
curr=root;
head=root;
}else{
//当前节点的左指针指向链表的尾部,链表的尾部的右指针指向当前节点
curr.right=root;
root.left=curr;
curr=root;
}
Convert(root.right);
return head;
}
}