牛客网 剑指Offer,一些值得记住的小题(二)

7.操作给定的二叉树,将其变换为源二叉树的镜像

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

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

    }

}
Solution类
public class Solution {
    public void Mirror(TreeNode root) {
        if(root==null){return ;}
        if(root.left==null&&root.right!=null){ 
            root.left=root.right; 
            root.right=null;
        }else if(root.right==null&&root.left!=null){
            root.right=root.left; 
            root.left=null;
        }else if(root.right!=null&&root.left!=null){
            TreeNode temp;
            temp=root.left;
            root.left=root.right;
            root.right=temp;
        }
        Mirror(root.left);
        Mirror(root.right);
    }
}
解析:再次强调,递归的截止条件一定要写,本体的思路还是很清晰的


8.输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        Stack<Integer> s = new Stack<Integer>();
        if(pushA.length==0||popA.length==0){return false;}
        int j=0;
        for(int i=0;i<pushA.length;i++){
            s.push(pushA[i]);
            while(j < popA.length&&s.peek() == popA[j]){
                s.pop();
                j++;
            }
        }
        if(s.empty()){
            return true;
        }
        else{
            return false;
        }
    }
}
解析:这一题很好的利用了栈的性质,很好的出栈序列的特点是,当一个后压栈的数字出现在了出栈序列里,那么在这个数之前压栈的数字一定要按照顺序弹出,如题意中的序列弹出序列中出现了4,那么3,2,1就一定要在之后的某一个地方不一定连续但一定要有序的弹出。本题的思路就是压栈序列第一个数首先压栈,和出栈序列第一个数比较,若不一样,继续取压栈序列里的数压栈,若一样则弹栈。直到最后看栈中是否为空,如果是空的则序列正确。


9.从上往下打印出二叉树的每个节点,同层节点从左至右打印。

TreeNode类:
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
Solution类:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        
        ArrayList<Integer> a = new ArrayList<Integer>();
        if(root==null){
            return a;
        }
        Queue<TreeNode> q = new LinkedList<TreeNode>() ;
        q.add(root);
        while(q.isEmpty()!=true){
        	TreeNode temp = q.poll();
        	if(temp.left!=null){
        		q.add(temp.left);
        	}
            if(temp.right!=null){
            	q.add(temp.right);
            }
            a.add(temp.val);
        }
        return a;
    }
}
解析:利用队列,每有一个结点出队列,就把这个这个节点的左右子树放进队列,最后出队列的顺序就是广度优先遍历


10.输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        int size = sequence.length;
        if(size==0){
            return false;
        }
        int i=0;
        while(--size!=0){
            while(sequence[i]<sequence[size])i++;
            while(sequence[i]>sequence[size])i++;
            if(i<size){
                return false;
            }
            i=0;
        }
        return true;
    }
}
解析:能成为后序遍历序列条件是每一个数前面的数都分为了两个部分,比这个数大的,然后紧接着是比这个数小的,日过有一个数不符合条件都不能成为合格的序列。


11.输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

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

    public TreeNode(int val) {
        this.val = val;
    }
}
Solution类:
import java.util.ArrayList;
public class Solution {
        ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> list = new ArrayList<Integer>();
        public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        if(root==null) return listAll;
        list.add(root.val);
        target = target - root.val;
        if(target==0&&root.left==null&&root.right==null){
            listAll.add(new ArrayList<Integer>(list));
        }
        FindPath(root.left,target);
        FindPath(root.right,target);
        list.remove(list.size()-1);
        return listAll;
    }
}
解析:这里list.remove(list.size()-1);是我认为这几行代码中最难理解的一句,我就理解了好久,问了好几个同学才勉强搞明白,思路是这样的,创建了一个listAll用来存放符合要求的所有路径,list存放某一条合格的序列,target指的是离目标还有多远,当符合条件(target==0&&root.left==null&&root.right==null)时就将这条合格的list加入listAll,如果不满足就进行递归看左子树或右子树是否有符合条件的路径,当左右子树的递归结束后,要把list中的最后一个元素去除,原因是list只有一个,也就是说里面只能存放一个路径,当当前节点左右子树都递归结束后,无论有没有符合条件的(符合条件的此时已经加入了listAll),都要弹出,目的要加入别的路径节点继续测试其他路径。


12.输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

/**
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 TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        Stack<TreeNode> s=new Stack<TreeNode>();
        TreeNode p=pRootOfTree;
        TreeNode pre=null;
        TreeNode root=null;
        boolean flag=true;
        while(p!=null||!s.isEmpty()){
            while(p!=null){
                s.push(p);
                p=p.left;
            }
            p=s.pop();
            if(flag==true){
                root=p;
                pre=root;
                flag=false;
                p=p.right;
            }else{
                pre.right=p;
                p.left=pre;
                pre=p;
                p=p.right;
            }
        }
        return root;
    }
}
解析:









猜你喜欢

转载自blog.csdn.net/shl_shl/article/details/61623922
今日推荐