一. 数据结构
题目1:
输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
算法实现思路:
从根结点开始前序遍历二叉树,到达叶子结点时,回退到当前叶子结点的父结点,继续比较与target是否相同
算法实现代码:
public class FindPath {
ArrayList<ArrayList<Integer>> pathList = new ArrayList<>();
ArrayList path = new ArrayList();
public ArrayList<ArrayList<Integer>> findPath(TreeNode root, int target) {
//异常case
if(root == null)
return pathList;
//正常case
path.add(root.val);
//1.根结点刚好和target相等
if(root.left == null && root.right == null && target == root.val)
{
//ArrayList带参数构造器?
pathList.add(new ArrayList<Integer>(path));
}
//2.根结点小于target,且左子树不为空
if(root.val <= target && root.left != null){
findPath(root.left,target-root.val);
}
//3.根结点小于target,且右子树不为空
if(root.val <= target && root.right != null)
{
findPath(root.right,target-root.val);
}
path.remove(path.size()-1);//回退到父节点
return pathList;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(3);
root.right.right = new TreeNode(2);
FindPath find = new FindPath();
find.findPath(root,6);
}
}
涉及java基础知识:
ArrayList常用方法
题目2:
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
算法实现思路:
分为三种情况:1. pHead有右孩子,则下一个结点是右孩子;2. pHead没有右孩子,且pHead本身是左孩子,则下一结点是pHead的父结点;3. pHead没有右孩子,且pHead本身是右孩子,则下一结点是使其为左子树结点的父结点,否则pHead是叶子结点,没有下一结点
算法实现代码:
class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
public class GetNext {
public TreeLinkNode getNext(TreeLinkNode pNode){
//异常case
if (pNode == null)
return null;
//正常case
//case1: pHead右子树不为空
if (pNode.right != null){
pNode = pNode.right;
while (pNode.left != null){
pNode = pNode.left;
}
return pNode;
}
//case2: pHead右子树为空,且pHead是左孩子
while (pNode.next != null){
if (pNode.next.left == pNode){
return pNode.next;
}
//case3:pHead右子树为空,且pHead是右孩子
pNode = pNode.next;
}
return null;
}
}
题目3:
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
算法实现思路:
分为三种情况:1. pHead有右孩子,则下一个结点是右孩子;2. pHead没有右孩子,且pHead本身是左孩子,则下一结点是pHead的父结点;3. pHead没有右孩子,且pHead本身是右孩子,则下一结点是使其为左子树结点的父结点,否则pHead是叶子结点,没有下一结点
算法实现代码:
public class Solution {
boolean isSymmetrical(TreeNode pRoot)
{
if (pRoot == null) {
return true;
}
return isMirror(pRoot.left, pRoot.right);
}
boolean isMirror(TreeNode node1,TreeNode node2) {
if (node1==null&&node2==null) {
return true;
}
if (node1==null||node2==null) {
return false;
}
return node1.val==node2.val?isMirror(node1.left, node2.right)&&isMirror(node1.right, node2.left):false;
}
}
题目4:
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
算法实现思路:
奇数行:按从左向右输出;偶数行:按从右向左输出
算法实现代码:
public class Print {
public ArrayList<ArrayList<Integer>> print(TreeNode pRoot){
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
if (pRoot == null)
return res;
//s1表示奇数,从右向左输出
Stack<TreeNode> s1 = new Stack<>();
//s2表示偶数,从左向右输出
Stack<TreeNode> s2 = new Stack<>();
//将根节点塞到s1中
s1.push(pRoot);
int level = 1;
//若s1,s2至少一个是非空
while (!s1.empty() || !s2.empty()) {
//奇数行
if (level % 2 != 0) {
ArrayList<Integer> list = new ArrayList<>();
//s1非空
while (!s1.empty()) {
TreeNode node = s1.pop();
if (node != null) {
list.add(node.val);
s2.push(node.left);
s2.push(node.right);
}
}
if (!list.isEmpty()) {
res.add(list);
level++;
}
}
//偶数行
else {
ArrayList<Integer> list = new ArrayList<>();
while (!s2.empty()) {
TreeNode node = s2.pop();
if (node != null) {
list.add(node.val);
s1.push(node.right);
s1.push(node.left);
}
}
if (!list.isEmpty()) {
res.add(list);
level++;
}
}
}
return res;
}
题目5:
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
算法实现思路:
实现Push操作:用栈1即可实现
实现Pop操作:需要考虑到栈1和栈2均为空的异常情况,将异常抛出去,将栈1出栈的数据入栈进去栈2,即可完成Pop操作
算法实现代码:
public class Solution1 {
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
public void push(int node){
//队列的push,从尾部push,和栈相同
//s1用来入栈
stack1.push(node);
}
public int pop() throws Exception{
//队列的pop,从头部出,和栈相反
//算法思想:将元素通过stack1输出,再塞进stack2,最后pop出栈
if (stack1.isEmpty() && stack2.isEmpty()){
//if中可以直接抛异常?
throw new Exception("栈为空!");
}
if (stack2.isEmpty()){
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
补充java基础知识点:
抛异常?