递归 算法专题

递归题目技巧

  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;//结果乘在一起
    }
}
相关推荐
森焱森8 分钟前
水下航行器外形分类详解
c语言·单片机·算法·架构·无人机
QuantumStack2 小时前
【C++ 真题】P1104 生日
开发语言·c++·算法
写个博客3 小时前
暑假算法日记第一天
算法
绿皮的猪猪侠3 小时前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
hie988943 小时前
MATLAB锂离子电池伪二维(P2D)模型实现
人工智能·算法·matlab
杰克尼4 小时前
BM5 合并k个已排序的链表
数据结构·算法·链表
.30-06Springfield4 小时前
决策树(Decision tree)算法详解(ID3、C4.5、CART)
人工智能·python·算法·决策树·机器学习
我不是哆啦A梦4 小时前
破解风电运维“百模大战”困局,机械版ChatGPT诞生?
运维·人工智能·python·算法·chatgpt
xiaolang_8616_wjl4 小时前
c++文字游戏_闯关打怪
开发语言·数据结构·c++·算法·c++20
small_wh1te_coder4 小时前
硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
linux·c语言·汇编·嵌入式硬件·算法·c