合并两个排序的链表、树的子结构、二叉树的镜像
2020/8/15
合并两个排序的链表
题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路:这是一个经常被各公司采用的面试题。首先分析合并两个链表的过程。我们分析从合并两个链表的头结点开始。链表1头结点的值小于链表2的头结点的值,因此链表1的头结点将是合并后链表的头结点。在剩余的结点中,链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点是剩余结点的头结点,把这个结点和之前已经合并好的链尾的尾结点链接起来。当我们得到两个链表中值较小的头结点并把它链接到已经合并的链表之后,两个链表剩余的结点依然是排序的,因此合并的步骤和之前的步骤是一样的。这就是典型的递归的过程,可根据递归函数完成这一合并过程。接下来,来解决鲁棒性问题,在本题中一旦输入空的链表就会引入空的指针,因此我们要对空链表单独处理,当第一个链表是空链表,也就是它的头结点是一个空指针时,那么把它和第二个链表合并,显然合并的结果就是第二个链表。同样,当输入的第二个链表的头结点是空指针的时候,我们把它和第一个链表合并得到的结果就是第一个空链表,如果两个链表都是空链表,合并的结果是得到一个空链表。
【代码】
package com.cc.jianzhi; /* 合并两个排序的链表 递归方法 */ public class Merge { public static void main(String[] args) { Merge m=new Merge(); ListNode list1=new ListNode(1); ListNode second=new ListNode(3); ListNode three=new ListNode(5); ListNode four=new ListNode(7); list1.next=second; second.next=three; three.next=four; ListNode list2=new ListNode(2); ListNode second2=new ListNode(4); ListNode three2=new ListNode(6); ListNode four2=new ListNode(8); list2.next=second2; second2.next=three2; three2.next=four2; System.out.println(m.Merge(list1,list2)); } public ListNode Merge(ListNode list1,ListNode list2){ if(list1==null){ return list2; } if(list2==null){ return list1; } if(list1.val<=list2.val){ list1.next=Merge(list1.next,list2); return list1; } list2.next=Merge(list1,list2.next); return list2; } }
树的子结构
题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:与树相关的问题通常会比链表的难,如果想加大面试的难度,树的题目是很多面试官的选择。要查找树A中是否存在和树B结构一样的子树,我们可以分两步:第一步可在树A中找到和B的根结点的值一样的结点R,第二步再判断树A中以R为根结点的子树是不是包含和树B一样的结构。第一步在树A中查找与根结点的值一样的结点,实际上是树的遍历,可以用递归的方法去遍历,也可以用循环的方法去遍历,由于递归的代码实现比较简洁,面试时,没有特别要求,通常都会采用递归方式。
【代码】
package com.cc.jianzhi; /* 树的子结构 题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) */ package com.cc.jianzhi; /* 树的子结构 题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) */ public class HasSubtree { public static void main(String[] args) { TreeNode root1=new TreeNode(8); TreeNode left=new TreeNode(8); TreeNode right=new TreeNode(7); root1.left=left; root1.right=right; left.left=new TreeNode(9); left.right=new TreeNode(2); left.right.left=new TreeNode(4); left.right.right=new TreeNode(7); TreeNode root2=new TreeNode(8); TreeNode left2=new TreeNode(9); TreeNode right2=new TreeNode(2); root2.left=left2; root2.right=right2; System.out.println(HasSubtree(root1,root2)); } public static boolean HasSubtree(TreeNode root1, TreeNode root2) { boolean flag; if(root1==null||root2==null){ return false; } flag = doesTree1HaveTree2(root1,root2); if(flag==true){ return true; }else{ return HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2); } } public static boolean doesTree1HaveTree2(TreeNode node1, TreeNode node2) { if(node2==null){ return true; } if(node1==null){ return false; } if(node1.val==node2.val){ return doesTree1HaveTree2(node1.left,node2.left)&&doesTree1HaveTree2(node1.right,node2.right); }else{ return false; } } }
二叉树的镜像
题目:操作给定的二叉树,将其变换为源二叉树的镜像。
思路:求一棵树的镜像的过程,先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子结点。当交换完所有非叶子结点的左右子结点之后,就得到了树的镜像。本题考察对二叉树的理解,本题实质上是利用树的遍历算法解决问题。
【代码】
package com.cc.jianzhi; /* 二叉树的镜像:操作给定的二叉树,将其变换为源二叉树的镜像。 */ //class TreeNode { // int val = 0; // TreeNode left = null; // TreeNode right = null; // // public TreeNode(int val) { // this.val = val; // } // @Override // public String toString() { // return "TreeNode{val:"+String.valueOf(val) +"}"; //} public class Mirror { public static void main(String[] args) { TreeNode root = new TreeNode(8); TreeNode left = new TreeNode(6); TreeNode right = new TreeNode(7); root.left = left; root.right = right; left.left = new TreeNode(9); left.right = new TreeNode(2); left.right.left = new TreeNode(4); left.right.right = new TreeNode(7); Mirror m = new Mirror(); m.Mirror(root); System.out.println(root); System.out.println(root.left); System.out.println(root.right); } public void Mirror(TreeNode root){ if(root == null){ return; } if(root.left==null && root.right==null){ return; } swapLR(root); Mirror(root.left); Mirror(root.right); } //交换左右结点 public void swapLR(TreeNode root){ TreeNode temp=root.left; root.left=root.right; root.right=temp; } }
- 剑指offer:合并两个排序的链表&树的子结构&二叉树的镜像
- python_lintcode_93. 平衡二叉树_165. 合并两个排序链表_453. 将二叉树拆成链表
- 牛客 剑 二维数组中的查找、重建二叉树(前中建树)、【链表】合并两个排序的链表(递归)、【数组】和为S的两个数字、【字符串】左旋转字符串(递归)、【树】把二叉树打印成多行(层数的处理)
- 反转链表后输出、合并两个排序链表、树的子结构 -- 漫漫算法路 刷题篇
- 二叉树的镜像 (剑指offer)!!!(两个有序链表的合并,链表的逆置)
- 剑指offer(十五)之合并两个排序的链表
- 合并两个排序链表
- java 合并两个排序的链表
- 合并两个排序的链表
- 剑指offer 面试题17 合并两个排序的链表-Java实现
- 【剑指Offer学习】【面试题17 ::合并两个排序的链表】
- 2.5 剑指offer 合并两个排序的链表
- 剑指Offer:面试题题17 合并两个排序的链表
- 合并两个排序链表
- 合并两个排序链表 - C++
- 合并两个排序链表
- 合并两个排序链表
- 剑指offer:合并两个排序的链表
- 有a,b两个已按学号升序排序的链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,仍按学号升序排列。
- 合并两个排序的链表