回溯理论基础及leetcode例题

学习参考

回溯

与递归相辅相成;回溯是递归的副产品,只要有递归就会有回溯。
回溯函数也就是递归函数,指的都是一个函数。

回溯搜索法

纯暴力搜索
解决的问题

组合问题:N个数里面按一定规则找出k个数的集合
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
排列问题:N个数按一定规则全排列,有几种排列方式(与组合差别,排列有元素顺序)
棋盘问题:N皇后,解数独等等

理解

抽象的不易理解;抽象为图形结构--树形结构
N叉树【树的宽度:集合的大小(for处理);深度:递归的深度(递归处理)】

模板

void backtracking(参数){
  if(终止条件){
    收集结果;
    return;
  }

  //单层搜索
   for(选择:本层集合中元素(树中节点孩子的数量就是集合的大小)){//集合元素集
      处理节点;
      backtracking(路径,选择列表);//递归函数;
      回溯操作; //(12,把2回溯,变13;没有回溯操作就会递归为123)
    }
  return;
}

递归里面嵌套for循环,for循环里又有递归

leetcode题目

组合

77.组合

for循环嵌套太多层了

树形结构
回溯理论基础及leetcode例题
不能取前面的的:因为组合是无序的,会重复;
每个节点都是一个for循环

回溯三部曲

递归函数参数返回值
确定终止条件
单层递归逻辑

伪代码

全局变量:二维数组res【返回值】
         一维数组path【单个结果】
//确定返回值参数
void backtracking(n,k,start){//n集合大小;k需要的子集合大小;start每个取值的开始;
  //确定终止条件
  if(path.size == k){
    res.add(path);
    return;
  }
  //单层递归逻辑
  //对于1,234节点
  for(i=start,i<=n;i++){
    path.push(i);//1
    backtracking(n,k,i+1);//遍历剩下的集合234;
    path.pop();//回溯过程
  } 
}

实现
java版本

class Solution {
    List<List<Integer>> res = new ArrayList<List<Integer>>();
    List<Integer> path = new ArrayList<Integer>();

    public List<List<Integer>> combine(int n, int k) {
        backtracking(n,k,1);
        return res;
    }

    public void backtracking(int n,int k,int start){
        if(path.size() == k){
            res.add(new ArrayList<>(path));//容易犯错误
            return;
        }

        for(int i=start;i<=n;i++){//i<=n -(k-path.size()) + 1 会减少运行时间【剪枝操作】
            path.add(i);
            backtracking(n,k,i+1);
            path.remove(path.size()-1);
        }
        
    }
}

问题:参考
在链表path里面添加值,然后把path链表添加进res链表中,在做算法题的时候,平时使用res.add(path),结果发现输出打印为空:

在链表path里面添加值,然后把path链表添加进res链表中,在做算法题的时候,平时使用res.add(path),结果发现输出打印为空: res.add(new ArrayList<>(path))和res.add(path)的区别
共同点: 都是向res这个ArrayList中填加了一个名为path的链表
不同点: res.add(new ArrayList(path)):开辟一个独立地址,地址中存放的内容为path链表,后续path的变化不会影响到res
res.add(path):将res尾部指向了path地址,后续path内容的变化会导致res的变化。

优化:剪枝
可以剪枝的地方就在递归中每一层的for循环所选择的起始位置。

如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。

回溯理论基础及leetcode例题
优化过程如下:

已经选择的元素个数:path.size();
所需需要的元素个数为: k - path.size();
列表中剩余元素(n-i) >= 所需需要的元素个数(k - path.size())
在集合n中至多要从该起始位置 : i <= n - (k - path.size()) + 1,开始遍历

原文链接:https://www.cnblogs.com/yunshalee/p/17312416.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:回溯理论基础及leetcode例题 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • JoshChen_php新手进阶高手不可或缺的规范介绍

    JoshChen_php新手进阶高手不可或缺的规范介绍 作为一名PHP程序员,熟练掌握编程语言的同时,规范的代码风格也是不可或缺的。本文将介绍一些PHP规范的相关内容,帮助PHP新手进阶为高手。 1. 代码风格规范 1.1. 缩进 在编写代码时,缩进是非常重要的。按照规范,我们应该在每个缩进级别使用4个空格。 1.2. 命名规范 在PHP中,我们应该遵循以下…

    数据结构 2023年5月17日
    00
  • Java数据结构顺序表用法详解

    Java数据结构顺序表用法详解 什么是顺序表? 在计算机科学中,顺序表(英语:Sequence)指的是一种线性数据结构,通常是用数组实现的。顺序表是一种顺序存放的线性表,其中的每个节点按照顺序依次排列。 顺序表的基本操作 顺序表主要包括以下几个基本操作: 创建顺序表 在顺序表中插入元素 从顺序表中删除元素 获取顺序表中的元素 判断顺序表是否为空 获取顺序表的…

    数据结构 2023年5月17日
    00
  • 使用C语言详解霍夫曼树数据结构

    使用C语言详解霍夫曼树数据结构 什么是霍夫曼树 霍夫曼树是一种带权路径长度最短的树,也称为最优二叉树,它是优化编码的核心算法。 在霍夫曼树中,每个叶子节点对应一个字符,该节点的权值为该字符出现的次数。当然,字符可以是任何数据类型。生成霍夫曼树后,在对每个字符进行编码时,字符在霍夫曼树中的路径即为其编码。(一般规定,一条从根到叶子的路径上只出现0或1,从根到某…

    数据结构 2023年5月17日
    00
  • 详解插入排序算法原理与使用方法

    插入排序算法是一种简单直观的排序算法,其基本思路是从序列的第二个元素开始,逐个将每个元素插入到已排序的序列中,直到所有元素都被插入完成。它的时间复杂度是O(n²),因此适用于小规模数据的排序。 下面我们来详细讲解一下插入排序算法的使用方法和实现过程: 算法思路 从序列的第二个元素开始,逐个将每个元素插入到已排序的序列中 对于未排序的元素,依次与已排序的元素进…

    算法 2023年3月27日
    00
  • Leetcode Practice — 栈和队列

    目录 155. 最小栈 思路解析 20. 有效的括号 思路解析 1047. 删除字符串中的所有相邻重复项 思路解析 1209. 删除字符串中的所有相邻重复项 II 思路解析 删除字符串中出现次数 >= 2 次的相邻字符 剑指 Offer 09. 用两个栈实现队列 239. 滑动窗口最大值 思路解析 155. 最小栈 设计一个支持 push ,pop ,…

    算法与数据结构 2023年4月17日
    00
  • 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解

    解析从源码分析常见的基于Array的数据结构动态扩容机制的详解 什么是动态扩容机制 动态扩容机制是指,当一个数据结构达到其容量限制时,自动增加容量大小以继续存储新的数据。在动态扩容时,需要考虑到时间和空间的平衡,因为扩容需要分配新的内存空间,在处理大量数据时,需要尽可能减少空间浪费和分配内存的时间消耗。 基于Array的数据结构 Array是一种连续存储的数…

    数据结构 2023年5月17日
    00
  • 数据结构之线性表

    Linear_list 类型定义 一个线性表是n个数据元素的有限序列,线性表中的元素个数n定义为线性表的长度,n=0时成为空表;抽象数据类型: InitList(&L) //构造空线性表L DestroyList(&L) //销毁线性表L ClearList(&L) //将L重置为空表 ListEmpty(L) //若L为空表返回TR…

    算法与数据结构 2023年4月25日
    00
  • Python使用sklearn库实现的各种分类算法简单应用小结

    下面是关于“Python使用sklearn库实现的各种分类算法简单应用小结”的完整攻略。 1. 分类算法简介 分类法是机器学习中的一要算法,它可以将数据集中的样本分为不同的类别。Python中常用的分类算法包括决策树、KNN、朴素贝叶斯、逻辑回归、支持向量机等。 2. Python实现分类算法 2.1 决策树 决策树是一种基于树形结构的算法它通过对数据集进行…

    python 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部