递归 算法专题

递归题目技巧

  1. 什么是递归
    函数自己调用自己的情况
  2. 为什么会用到递归
    本质: 主问题, 可以拆分成相同的子问题
    子问题, 又可以拆分出相同的子问题
  3. 如何理解递归?
    宏观的看待递归的过程
    1)不要在意递归的细节展开图
    2)把递归的函数当成一个黑盒
    3)相信这个黑盒一定能够完成这个任务
  4. 如果写好一个递归?
    1)先找到相同的子问题(变得值)-----函数头的设计
    2)只关心某个子问题是如何解决的-----函数体的书写
    3)注意一下函数递归的出口
  5. 循环(迭代)和递归本质是可以相互转化的
    循环, 适用于只有一层递归的情况, 例如链表
    递归, 适合多层, 例如二叉树, 多叉树...

一. 汉诺塔问题

汉诺塔问题

java 复制代码
class Solution {
    public void hanota(List<Integer> a, List<Integer> b, List<Integer> c) {
        dfs(a, b, c, a.size());// 从a借助b移动到c, 移动n个盘子
    }

    public void dfs(List<Integer> a, List<Integer> b, List<Integer> c, int n) {
        if (n == 1) {
            c.add(a.remove(a.size() - 1));
            return;
        }
        dfs(a, c, b, n - 1);
        c.add(a.remove(a.size() - 1));
        dfs(b, a, c, n - 1);

    }
}

二. 合并两个有序链表

合并两个有序链表

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {//合并两个有序链表
        if(l1 == null) return l2;
        if(l2 == null) return l1;

        if(l1.val < l2.val){
            l1.next = mergeTwoLists(l1.next, l2);//l1小, 合并l1.next 和 l2两个有序链表
            return l1;
        }else{
            l2.next = mergeTwoLists(l1, l2.next);//l2小, 合并l2.next 和 l1两个有序链表
            return l2;
        }
        
    }
}

三. 反转链表

反转链表

java 复制代码
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode newHead = reverseList(head.next);//将head结点后面的逆序, 返回逆序后的头结点
        head.next.next = head;//将head结点插在逆序链表最后
        head.next = null;//将head.next置为空
        return newHead;
    }
}

四. 两两交换链表中的结点

两两交换链表中的结点

java 复制代码
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode newHead = swapPairs(head.next.next);//将head.next.next 后面的链表两两交换, 返回头结点
        ListNode ret = head.next;
        head.next.next = head;//将前两个链表交换
        head.next = newHead;

        return ret;

    }
}

五. pow(x, n)

算法: 快速幂

实现快速幂: 1. 递归 2. 循环

java 复制代码
class Solution {
    public double myPow(double x, int n) {
        return n < 0 ? 1.0 / pow(x, -n): pow(x, n);
    }
    public double pow(double x, int n){
         if(n == 0) return 1.0;
        double tmp = pow(x, n / 2);//先算一半
        return n % 2 == 0? tmp * tmp : tmp * tmp * x;//结果乘在一起
    }
}
相关推荐
Renas_TJOvO8 分钟前
排序算法汇总
java·数据结构·算法
Stardep9 分钟前
算法2—八大常用排序算法(下)
c语言·数据结构·笔记·算法·排序算法·1024程序员节
黑不溜秋的20 分钟前
C++ 模板专题 - 标签分派(Tag Dispatching)
开发语言·c++·算法
爱上语文26 分钟前
LeetCode每日一题
java·算法·leetcode
ProcedureStone37 分钟前
【算法】排序算法总结
c++·算法·排序算法
哦哦~92141 分钟前
Fluent和深度学习算法驱动的流体力学计算与应用
人工智能·深度学习·学习·算法
千里马-horse1 小时前
在OpenCL 中输出CLinfo信息
开发语言·c++·算法·opencl·1024程序员节
Y.O.U..1 小时前
Linux-计算机网络-epoll的LT,ET模式
linux·服务器·计算机网络·算法·1024程序员节