链表反向打印
题目描述:
从尾到头反过来打印出每个结点的值。
三种方法:
- 递归
- 利用头插法的性质
- 栈
第二个和第三个都没有问题,问题出现在了递归上。
根据参考的代码,递归这样写:
public static ArrayList<Integer> printListReversed(ListNode listnode) {
ArrayList<Integer> ret = new ArrayList<Integer>();
if(listnode != null) {
ret.addAll(printListReversed(listnode.next));
ret.add(listnode.val);
}
return ret;
}
问题:我不太懂为什么用add还要再用一个addAll,原因是在这个方法中,每调用一次就要新建一个为null的链表。
解决:将ret链表定义为全局变量,这样就只用add就可以了。
为什么不懂:不熟悉递归。
所有代码如下:
package jianzhiOffer;
import java.util.*;
class ListNode{
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
this.next = null;
}
}
public class PrintListReversedOrder {
public static ArrayList<Integer> printListReversed(ListNode listnode) {
ArrayList<Integer> ret = new ArrayList<Integer>();
if(listnode != null) {
printListReversed(listnode.next);
//ret.addAll(printListReversed(listnode.next));
//ret.addAll(r);
ret.add(listnode.val);
//System.out.print(listnode.val + "*");
/*for(int i=0; i<ret.size(); i++) {
System.out.print(ret.get(i) + "_" );
}*/
}
return ret;
}
public static ArrayList<Integer> headToTail(ListNode node){
ListNode head = new ListNode(-1);
while(node != null) {
ListNode temp = node;
temp = node.next;
node.next = head.next;
head.next = node;
node = temp;
}
while(head.next != null) {
head = head.next;
System.out.print(head.val + " ");
}
ArrayList<Integer> ret = new ArrayList<Integer>();
return ret;
}
public static ArrayList<Integer> StackListReversed(ListNode listnode){
ArrayList<Integer> ret = new ArrayList<Integer>();
Stack<ListNode> stack = new Stack<ListNode>();
while(listnode != null) {
stack.push(listnode);
listnode = listnode.next;
}
while(!stack.isEmpty()) {
ret.add(stack.pop().val);
}
for(int i=0; i<ret.size(); i++) {
System.out.print(ret.get(i) + " " );
}
return ret;
}
public static void display(ListNode listnode) {
while(listnode != null) {
System.out.print(listnode.val + " ");
listnode = listnode.next;
}
System.out.println();
}
public static void main(String[] args) {
ListNode n1 = new ListNode(2);
ListNode n2 = new ListNode(3);
ListNode n3 = new ListNode(4);
n1.next = n2;
n2.next = n3;
//display(n1);
StackListReversed(n1);
//ArrayList<Integer> ret = printListReversed(n1);
//ArrayList<Integer> ret2 = headToTail(n1);
/*for(int i=0; i<ret.size(); i++) {
System.out.print(ret.get(i) + " ");
}
System.out.println();*/
}
}
重建二叉树
题目描述:
根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。
- 根据前序遍历找到划分好的各个树的root结点
- 再根据中序遍历找出当前左子树的长度,确定当前父节点的左子树与右子树,并进行赋值
- 分别对左子树和右子树进行递归找出所有的子树
- 当返回值为null时结束,返回递归的上一层
二叉树的display()还没搞懂!!!
代码如下:
package jianzhiOffer;
import java.util.*;
class TreeNode{
TreeNode leftChild;
TreeNode rightChild;
int value;
public TreeNode(int val) {
leftChild = null;
rightChild = null;
value = val;
}
}
public class ContructBinaryTree {
private static Map<Integer, Integer> indexForInOrder = new HashMap<>();
private static TreeNode reContructBinaryTree(int []pre, int []in) {
for(int i=0; i<in.length; i++) {
indexForInOrder.put(in[i], i);
}
return reContructBinaryTree(pre, 0, pre.length-1,0);
}
public static TreeNode reContructBinaryTree(int []pre, int preL, int preR,
int inL) {
//当传入的pre只有一个值时,preL==preR,此时的结点为叶节点
if(preL>preR) {
return null;
}
TreeNode root = new TreeNode(pre[preL]);
int leftTreeSize = indexForInOrder.get(pre[preL]) - inL;
root.leftChild = reContructBinaryTree(pre, preL+1, preL+leftTreeSize, inL);
root.rightChild = reContructBinaryTree(pre, preL+leftTreeSize+1, preR, inL+leftTreeSize+1);
return root;
}
public static void display(TreeNode root) {
Stack<TreeNode> globalStack = new Stack<TreeNode>();
globalStack.push(root);
int nBlanks = 16;
boolean isRowEmpty = false;
System.out.println("··········································");
while(isRowEmpty == false) {
Stack<TreeNode> localStack = new Stack<TreeNode>();
isRowEmpty = true;
for(int j=0; j<nBlanks; j++) {
System.out.print(' ');
}
while(globalStack.isEmpty() == false) {
TreeNode temp = (TreeNode)globalStack.pop();
if(temp != null) {
System.out.print(temp.value);
localStack.push(temp.leftChild);
localStack.push(temp.rightChild);
if(temp.rightChild != null
|| temp.leftChild != null)
isRowEmpty = false;
}
else {
System.out.print("--");
localStack.push(null);
localStack.push(null);
}
for(int j=0; j<nBlanks*2-2; j++) {
System.out.print(" ");
}
}
System.out.println();
nBlanks /= 2;
while(localStack.isEmpty() == false) {
globalStack.push(localStack.pop());
}
}
System.out.println("··········································");
}
public static void preOrder(TreeNode localRoot) {
if(localRoot != null) {
System.out.print(localRoot.value + " ");
preOrder(localRoot.leftChild);
preOrder(localRoot.rightChild);
}
}
public static void main(String[] args) {
int[] pre = new int[] {3, 9, 20, 15, 7};
int[] in = new int[] {9, 3, 15, 20, 7};
TreeNode root = reContructBinaryTree(pre, in);
preOrder(root);
System.out.println();
display(root);
}
}