算法与数据结构之递归

要点

  • 搞清楚递归函数的作用
  • 处理当前状态和下一递归状态的关系
  • 处理好递归的出口

举例

  • 反转链表
    • 当前递归函数的作用:反转链表,并返回新的头结点。
    • 当前状态和下一递归状态的关系:递归调用ReverseList(head.next),函数会返回新的头结点,我们需要处理好当前状态和下一状态的关系。
    • 递归的出口:如果head或者head.next为null,直接返回head;
    • 代码
   public class Solution {
       public ListNode ReverseList(ListNode head) {
           if (head == null || head.next == null) {
               return head;
           }
           ListNode newHead = ReverseList(head.next);
           // 处理状态
           head.next.next = head;
           head.next = null;
           return newHead;
       }
   }
  • 最近公共节点
    • 当前递归函数的作用:返回最近公共节点
    • 当前状态和下一递归状态的关系:判断lowestCommonAncestor(root.left)lowestCommonAncestor(root.right)是否为null。如果两个都不为null,则返回当前节点;如果某一个为null,返回另一个节点;
    • 递归的出口:root为null或者root等于left或者root等于right;
    • 代码
  class Solution {
      public TreeNode lowestCommonAncestor(TreeNode root, TreeNode o1, TreeNode o2) {
          if (root == null || root == o1 || root == o2) {
              return root;
          }
          TreeNode left = lowestCommonAncestor(root.left, o1, o2);
          TreeNode right = lowestCommonAncestor(root.right, o1, o2);
          if (left != null && right != null) {
              return root;
          }
          if (left != null) {
              return left;
          }
          if (right != null) {
              return right;
          }
          return null;
      }
  }
  • 最小的K个数
    • 当前递归函数的作用:排序前k个数,即在(left, right)范围,将key = arr[left]放置到合适的位置,使得左边的值都小于key,右边的值都大于key;
    • 当前状态和下一状态的关系:(left, i - 1)都是小于等于key,(i + 1, right)都是大于等于key。如果当前下标i等于k - 1,则可以直接return;如果当前下标i大于k - 1,则需要调用helper(arr, left, i - 1);如果当前下标小于k - 1,则递归调用helper(arr, i + 1, right)
    • 递归的出口:left < right;
    • 代码
public class Solution {
    private void quickSortImporvment(int[] nums, int left, int right, int k) {
        if (left < right) {
            int randomIndex = new Random().nextInt(right - left + 1) + left;
            swap(nums, left, randomIndex);
            int i = left, j = right, key = nums[i];
            while (i < j) {
                while (i < j && nums[j] >= key) {
                    j--;
                }
                if (i < j) {
                    nums[i] = nums[j];
                }
                while (i < j && nums[i] <= key) {
                    i++;
                }
                if (i < j) {
                    nums[j] = nums[i];
                }
            }
            nums[i] = key;
            if (i == k - 1) {
                return ;
            } else if (i > k - 1) {
                quickSortImporvment(nums, left, i - 1, k);
            } else {
                quickSortImporvment(nums, i + 1, right, k);
            }
        }
    }

    private void swap(int[] arr, int index1, int index2) {
        int temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值