【剑指Offer】之链表反向打印和重建二叉树

链表反向打印

题目描述:

从尾到头反过来打印出每个结点的值。

三种方法:

  1. 递归
  2. 利用头插法的性质

第二个和第三个都没有问题,问题出现在了递归上。

根据参考的代码,递归这样写:

	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);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值