递归到底怎么写?
这是刷题之旅的第一篇,算是对递归的一个总结,题目主要包含链表和二叉树。之前考虑递归总是考虑递归的每一步操作,巴不得把细节全部弄清楚才能理解,后来看了很多博客,发现递归是有它的范式的,我们主要关注三个步骤就行了:
- 整个递归的终止条件。
- 一次递归需要的操作
- 给上一级的返回值
leetcode24:两两交换链表中的节点。给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
public ListNode swapPairs(ListNode head) {
//1.终止条件
if(head == null || head.next == null)
return head;
//2.每次递归交换三个节点的位置:head,head.next,swapPairs(head.next.next)
ListNode pNode = head.next;
head.next = swapPairs(pNode.next);
pNode.next = head;
//3.递归返回值
return pNode;
}
leetcode101:给定一个二叉树,检查它是否是镜像对称的。
public boolean isSymmetric(TreeNode root){
if(root == null)
return true;
else
return isSymmetric(root.left,root.right);
}
//判断两棵子树是否镜像对称
private boolean isSymmetric(TreeNode root1,TreeNode root2){
//都为空,返回true
if(root1 == null && root2 == null)
return true;
if(root1 == null || root2 == null)
return false;
return root1.val == root2.val
&&isSymmetric(root1.left,root2.right)
&&isSymmetric(root1.right,root2.left);
}
leetcode104:给定一个二叉树,找出其最大深度。
//递归一行的写法:
public int maxDepth(TreeNode root){
return root == null?0:Math.max(maxDepth(root.right),maxDepth(root.left))+1;
}
//常规写法:
public int maxDepth(TreeNode root){
//1.终止条件
if(root == null)
return 0;
//2.一次递归分别求出左子树的最大深度和右子树的最大深度
int leftDepth = maxDepth(root.left);
int rightDepth = maxDepth(root.right);
//3.返回二者最大值+1(根节点)
return Math.max(leftDepth,rightDepth)+1;
}
leetcode110:给定一个二叉树,判断它是否是高度平衡的二叉树。
public boolean isBalanced(TreeNode root) {
//根节点为空,返回true
if(root == null)
return true;
//满足左右子树高度差小于等于1,那就接着判断左右子树是不是二叉树
if(Math.abs(getDepth(root.left)-getDepth(root.right))<=1)
return (isBalanced(root.left) && isBalanced(root.right));
//不满足左右子树高度差小于等于1,返回false
else
return false;
}
//获取树的深度
public int getDepth(TreeNode root){
if( root == null ) return 0;
int left = getDepth(root.left);
int right = getDepth(root.right);
return Math.max(left,right)+ 1;
}
leetcode111:二叉树的最小深度,最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
public int minDepth(TreeNode root) {
//递归终止
if (root == null) return 0;
if ((root.left == null) && (root.right == null)) return 1;
//每次递归要做的是求出左右子树的最小深度
int min_depth = Integer.MAX_VALUE;
if (root.left != null) {
min_depth = Math.min(minDepth(root.left), min_depth);
}
if (root.right != null) {
min_depth = Math.min(minDepth(root.right), min_depth);
}
//返回最终的深度
return min_depth + 1;
}
leetcode206:反转链表
public ListNode reverseList(ListNode head){
//终止条件
if( head == null||head.next == null) return head;
//每次递归反转两个节点
ListNode pNode = reverseList(head.next);
head.next.next = head;
head.next = null;
//返回递归的头节点
return pNode;
}
leetcode226:反转二叉树
public TreeNode invertTree(TreeNode root) {
//终止条件:节点为空
if(root == null)
return null;
//每次递归交换左右子树
TreeNode rightNode = invertTree(root.right);
TreeNode leftNode = invertTree(root.left);
root.right = leftNode;
root.left = rightNode;
//返回根节点
return root;
}
leetcode617:合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
//终止条件
if(t1 == null){
return t2;
}
if(t2 == null){
return t1;
}
//每次递归对应相加
TreeNode result = new TreeNode(t1.val + t2.val);
result.left = mergeTrees(t1.left,t2.left);
result.right = mergeTrees(t1.right,t2.right);
//递归返回值
return result;
}