《剑指offer》算法题第五天
今日题目:
- 反转链表
- 合并两个排序的链表
- 树的子结构
- 二叉树的镜像
- 对称二叉树
今日重点是1反转链表,3树的子结构,以及5对称二叉树。
1. 反转链表
题目描述:
输入一个链表,反转链表后,输出链表的所有元素。
思路: 这道题可以有递归和迭代两种实现方法,较为经典,其中迭代又有头插和非头插两种方法。
代码如下:
1 //递归实现 2 public ListNode ReverseList(ListNode head) { 3 if(head == null || head.next == null) 4 return head; 5 ListNode newNode = ReverseList(head.next); 6 head.next.next = head; 7 head.next = null; 8 return newNode; 9 } 10 11 12 //迭代实现 13 //非头插法 14 public ListNode ReverseList(ListNode head) { 15 if(head == null || head.next == null) 16 return head; 17 ListNode pre = head; 18 ListNode cur = head.next; 19 ListNode next = cur.next; 20 while(cur != null){ 21 next = cur.next; 22 cur.next = pre; 23 pre = cur; 24 cur = next; 25 } 26 head.next = null; 27 return pre; 28 } 29 30 //头插法 31 public ListNode ReverseList(ListNode head) { 32 if(head == null || head.next == null) 33 return head; 34 ListNode dummy = new ListNode(0); 35 ListNode cur = head; 36 while(cur != null){ 37 ListNode tmp = cur.next; 38 cur.next = dummy.next; 39 dummy.next = cur; 40 cur = tmp; 41 } 42 return dummy.next; 43 }
3. 树的子结构
题目描述:
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路: 这道题其实不难,利用树的遍历就能够解决,但是要写得漂亮很难,下面贴出漂亮和不漂亮的写法。
代码如下:
漂亮的
1 public boolean HasSubtree(TreeNode root1,TreeNode root2) { 2 boolean result = false; 3 if(root1 != null && root2 != null){ 4 result = isSubtree(root1,root2); 5 if(!result) 6 result = HasSubtree(root1.left,root2); 7 if(!result) 8 result = HasSubtree(root1.right,root2); 9 } 10 return result; 11 } 12 13 public boolean isSubtree(TreeNode root1,TreeNode root2){ 14 if(root2 == null) 15 return true; 16 if(root1 == null) 17 return false; 18 if(root1.val != root2.val) 19 return false; 20 return isSubtree(root1.left,root2.left)&& 21 isSubtree(root1.right,root2.right); 22 }
不漂亮的。。
1 public boolean HasSubtree(TreeNode root1,TreeNode root2) { 2 if(root1 == null || root2 == null) 3 return false; 4 if(isSubtree(root1,root2)) 5 return true; 6 else{ 7 boolean left = false, right = false; 8 left = HasSubtree(root1.left,root2); 9 right = HasSubtree(root1.right,root2); 10 return left || right; 11 } 12 } 13 14 public boolean isSubtree(TreeNode root1,TreeNode root2){ 15 if(root1 == null && root2 == null) 16 return true; 17 if(root1 == null) 18 return false; 19 if(root2 == null) 20 return true; 21 if(root1.val != root2.val) 22 return false; 23 return isSubtree(root1.left,root2.left)&& 24 isSubtree(root1.right,root2.right); 25 }
5. 对称二叉树
题目描述:
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
思路:递归实现,注意递归的节点顺序。
代码如下:
1 boolean isSymmetrical(TreeNode pRoot) 2 { 3 if(pRoot == null) return true; 4 return isSym(pRoot.left,pRoot.right); 5 } 6 7 boolean isSym(TreeNode left,TreeNode right){ 8 if(left == null && right == null) 9 return true; 10 if(left == null || right == null) 11 return false; 12 if(left.val != right.val) 13 return false; 14 return isSym(left.left,right.right) && 15 isSym(left.right,right.left); 16 }