打表法结合经典案例从原理到实战详解

    • 一、打表法基本信息
      • 1.1 打表法定义
      • 1.2 打表法适用场景
      • 1.3 打表法的优缺点
    • 二、打表法经典案例解析
      • 2.1 快速计算斐波那契数列
        • 2.1.1 问题描述
        • 2.1.2 打表思路
        • 2.1.3 Java代码实现
        • 2.1.4 复杂度分析
      • 2.2 快速判断质数(埃氏筛法结合打表)
        • 2.2.1 问题描述
        • 2.2.2 打表思路
        • 2.2.3 Java代码实现
        • 2.2.4 复杂度分析
      • 2.3 动态规划问题的打表优化(最长公共子序列)
        • 2.3.1 问题描述
        • 2.3.2 打表思路
        • 2.3.3 Java代码实现
        • 2.3.4 复杂度分析
    • 三、打表法的优化与注意事项
      • 3.1 优化技巧
      • 3.2 注意事项

打表法是一种实用且高效的优化手段,它通过预先计算并存储问题的答案,在实际运行时直接查表获取结果,避免重复计算,从而大幅提升程序运行效率。本文我将结合多个经典案例,深入讲解打表法的应用场景、实现方式及优化技巧,帮你掌握这一重要的编码方法。

一、打表法基本信息

1.1 打表法定义

打表法,顾名思义,就是将问题的答案预先计算出来并存储在“表”(数组、哈希表等数据结构)中,后续遇到相同问题时,直接从表中读取答案,无需再次进行复杂计算。这种方法适用于问题的输入范围有限、计算过程耗时较长,且答案可以提前计算的场景。

1.2 打表法适用场景

  • 数据范围固定:输入数据的范围较小且确定,例如计算1到10000以内的所有质数、1到100的阶乘等。
  • 计算复杂耗时:问题的计算过程复杂,重复计算会消耗大量时间,如一些动态规划问题、数论问题等。
  • 答案可预先计算:问题的答案可以在程序运行前通过其他方式(如编写专门的计算程序、数学推导等)计算得出,并且不会随着程序运行过程而改变。

1.3 打表法的优缺点

  • 优点
    • 提高效率:避免重复计算,显著减少程序运行时间。
    • 简化逻辑:在实际使用时,只需查表操作,简化了程序的运行逻辑。
  • 缺点
    • 占用空间:需要预先存储答案,可能会占用较多内存空间。
    • 灵活性差:打表结果依赖于预先确定的输入范围,若输入范围改变,可能需要重新打表。

二、打表法经典案例解析

2.1 快速计算斐波那契数列

2.1.1 问题描述

斐波那契数列是一个经典的数列,其定义为: F ( 0 ) = 0 F(0) = 0 F(0)=0 F ( 1 ) = 1 F(1) = 1 F(1)=1 F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n) = F(n - 1) + F(n - 2) F(n)=F(n1)+F(n2) n ≥ 2 n \geq 2 n2)。现在需要快速计算斐波那契数列中第n项的值( 0 ≤ n ≤ 100 0 \leq n \leq 100 0n100)。

2.1.2 打表思路

由于n的范围较小且确定( 0 ≤ n ≤ 100 0 \leq n \leq 100 0n100),可以预先使用循环计算出斐波那契数列前101项的值,并存储在数组中。后续需要查询时,直接从数组中获取对应项的值。

2.1.3 Java代码实现
public class FibonacciTable {private static final int[] fibonacciTable;static {fibonacciTable = new int[101];fibonacciTable[0] = 0;fibonacciTable[1] = 1;for (int i = 2; i < 101; i++) {fibonacciTable[i] = fibonacciTable[i - 1] + fibonacciTable[i - 2];}}public static int getFibonacci(int n) {if (n < 0 || n > 100) {throw new IllegalArgumentException("n的范围应在0到100之间");}return fibonacciTable[n];}public static void main(String[] args) {System.out.println(getFibonacci(10));  // 输出55}
}
2.1.4 复杂度分析
  • 打表时间复杂度:打表过程通过一次循环计算,时间复杂度为 O ( n ) O(n) O(n),这里n = 101
  • 查询时间复杂度:查询时直接从数组中取值,时间复杂度为 O ( 1 ) O(1) O(1)
  • 空间复杂度:使用一个长度为101的数组存储打表结果,空间复杂度为 O ( n ) O(n) O(n)

2.2 快速判断质数(埃氏筛法结合打表)

2.2.1 问题描述

给定一个整数n 1 ≤ n ≤ 1000000 1 \leq n \leq 1000000 1n1000000),需要快速判断它是否为质数。

2.2.2 打表思路

使用埃氏筛法预先计算出1到1000000范围内的所有质数,并将结果存储在布尔数组中,true表示对应下标是质数,false表示不是质数。后续判断某个数是否为质数时,直接从数组中读取对应位置的值。

2.2.3 Java代码实现
public class PrimeTable {private static final boolean[] primeTable;static {primeTable = new boolean[1000001];Arrays.fill(primeTable, true);primeTable[0] = primeTable[1] = false;for (int i = 2; i * i <= 1000000; i++) {if (primeTable[i]) {for (int j = i * i; j <= 1000000; j += i) {primeTable[j] = false;}}}}public static boolean isPrime(int n) {if (n < 1 || n > 1000000) {throw new IllegalArgumentException("n的范围应在1到1000000之间");}return primeTable[n];}public static void main(String[] args) {System.out.println(isPrime(17));  // 输出trueSystem.out.println(isPrime(18));  // 输出false}
}
2.2.4 复杂度分析
  • 打表时间复杂度:埃氏筛法打表过程的时间复杂度为 O ( n log ⁡ log ⁡ n ) O(n \log \log n) O(nloglogn),这里n = 1000000
  • 查询时间复杂度:查询时直接从数组中取值,时间复杂度为 O ( 1 ) O(1) O(1)
  • 空间复杂度:使用一个长度为1000001的布尔数组存储打表结果,空间复杂度为 O ( n ) O(n) O(n)

2.3 动态规划问题的打表优化(最长公共子序列)

2.3.1 问题描述

给定两个字符串text1text2,返回这两个字符串的最长公共子序列的长度。例如,输入text1 = "abcde"text2 = "ace",输出为3,因为最长公共子序列是"ace"

2.3.2 打表思路

在一些算法竞赛或特定场景中,如果已知输入字符串的长度范围有限(假设两个字符串长度都不超过100),可以预先计算出所有可能长度的字符串组合的最长公共子序列长度,并存储在二维数组中。实际使用时,根据输入字符串的长度直接从表中获取结果。

2.3.3 Java代码实现
public class LCSLookupTable {private static final int[][] lcsTable;static {lcsTable = new int[101][101];for (int i = 1; i < 101; i++) {for (int j = 1; j < 101; j++) {// 这里只是简单示例初始化,实际计算应使用动态规划lcsTable[i][j] = 0; }}// 假设这里有一个完整的动态规划计算过程填充lcsTable,此处省略}public static int longestCommonSubsequence(String text1, String text2) {int m = text1.length();int n = text2.length();if (m > 100 || n > 100) {throw new IllegalArgumentException("字符串长度应不超过100");}return lcsTable[m][n];}public static void main(String[] args) {System.out.println(longestCommonSubsequence("abc", "ac"));  // 假设打表结果正确,输出2}
}
2.3.4 复杂度分析
  • 打表时间复杂度:如果使用动态规划计算并填充二维表,时间复杂度为 O ( M × N ) O(M \times N) O(M×N),其中MN分别为预先设定的字符串长度上限(这里M = N = 100) 。
  • 查询时间复杂度:查询时直接从二维数组中取值,时间复杂度为 O ( 1 ) O(1) O(1)
  • 空间复杂度:使用一个101×101的二维数组存储打表结果,空间复杂度为 O ( M × N ) O(M \times N) O(M×N)

三、打表法的优化与注意事项

3.1 优化技巧

  • 压缩存储:当打表结果占用空间较大时,可以考虑使用压缩算法(如位图、哈希压缩等)减少存储空间。例如,在存储大量布尔值的打表结果时,可使用位图表示,将多个布尔值存储在一个字节中。
  • 分块打表:对于输入范围较大的情况,可以采用分块打表的方式。将输入范围划分为多个小块,每个小块单独打表,查询时先确定所在块,再在块内查询,既能减少内存占用,又能保持较高的查询效率。

3.2 注意事项

  • 范围匹配:确保打表的范围覆盖实际使用时的输入范围,否则可能会出现越界或无法查询到结果的情况。
  • 数据更新:如果问题的答案会随着某些条件改变而变化,打表法可能不适用,或者需要重新打表。
  • 内存限制:在使用打表法时,要注意程序的内存限制,避免因打表占用过多内存导致程序运行出错。

That’s all, thanks for reading!
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86201.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86201.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/86201.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(LeetCode 面试经典 150 题 )121. 买卖股票的最佳时机 (遍历)

题目&#xff1a;121. 买卖股票的最佳时机 思路&#xff1a;遍历&#xff0c;维护已遍历过的元素中的最小值&#xff0c;时间复杂度0(n)。 C版本&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int mnprices[0];int mx0;for(int i1;i&…

(洛谷)P4447 [AHOI2018初中组] 分组

题目描述 小可可的学校信息组总共有 n 个队员&#xff0c;每个人都有一个实力值 ai​。现在&#xff0c;一年一度的编程大赛就要到了&#xff0c;小可可的学校获得了若干个参赛名额&#xff0c;教练决定把学校信息组的 n 个队员分成若干个小组去参加这场比赛。 但是每个队员都…

PLA/PHA生物降解化妆品包装材料的稳定性与货架期契合性研究

更多案例&#xff1a;https://npmatc.niicapm.com/ 在可持续发展理念的推动下&#xff0c;化妆品行业正经历一场绿色变革。环保聚合物在包装领域的应用已成为重要趋势&#xff0c;这不仅源于消费者对生态友好产品的需求&#xff0c;更基于全球塑料污染治理的紧迫性。化妆品包装…

STM32[笔记]--4.嵌入式硬件基础

4.嵌入式硬件基础 4.1认识上官二号开发板 主控芯片:STM32F103C8T6高速晶振:8M低速晶振:32.768kLED:5颗KEY:3个 主控芯片内部的资源如下项目介绍内核Cortex-M3Flsah64K*8bitSRAM20K*8bitGPIO37个GPIO,分别为PA0-PB15,PC13-PC15,PD0-PD1ADC2个12bitADC合计12了通道,外部通…

【LLaMA-Factory 实战系列】一、数据准备篇 - 从文本到多模态的完整流程

【LLaMA-Factory 实战系列】一、数据准备篇 - 从文本到多模态的完整流程 1. 引言2. LLaMA-Factory 数据格式概述2.1 Alpaca 格式2.2 ShareGPT 格式 3. 文本数据准备3.1 Alpaca 格式示例3.2 ShareGPT 格式示例3.3 预训练数据格式 4. 多模态数据准备4.1 图像数据准备4.2 视频数据…

JuiceFS 集群部署详细指南:使用 SeaweedFS 作为数据存储,ETCD 作为元数据存储

1. 概述 本指南将详细介绍如何部署一个 JuiceFS 集群,其中数据存储层采用高性能的分布式对象存储 SeaweedFS,元数据存储层采用强一致性的分布式键值存储 ETCD。这种组合方案旨在为用户提供一个高性能、高可用、易于扩展且数据强一致的分布式文件系统解决方案,特别适用于云原…

【数字后端】- 什么是NDR规则?

NDR是指与工艺库的默认规则&#xff08;DR&#xff09;不同的特殊物理规则&#xff1a; 常见的有&#xff1a; 间距规则&#xff08;spacing&#xff09;&#xff1a;增加信号线与邻近线之间的距离&#xff0c;降低Crosstalk串扰。线宽规则&#xff08;width&#xff09;&…

B2B 商城定制的优势:解锁企业数字化转型新动力

精准适配业务流程&#xff0c;贴合企业运营特色​ 每一家企业都有独特的业务流程、运营模式与管理需求。标准化的 B2B 商城往往难以完全满足企业个性化的业务需求&#xff0c;而定制化商城则能够深入剖析企业业务细节&#xff0c;从采购、销售、库存管理到财务管理等全流程&am…

osg实例绘制

#include <osg/Geometry> #include <osg/Geode> #include <osg/Program> #include <osg/VertexAttribDivisor> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <random> // 创建单个立方体几何体&…

Qt面试题汇总

目录 1. 简单说一下Qt 2. 用过QT中的哪些模块&#xff1f; 3. 说一些你常用的Qt控件&#xff1f; 4. Qt中如何创建一个窗口&#xff1f; 5. 说一下QT中创建控件的方式? 6. 说一下Qt中信号和槽机制是什么&#xff1f; 7. 说一下QT信号与槽机制原理&#xff1f; 8. 如何自…

【stm32】标准库学习——USART串口

目录 一、USART串口 1.串口参数及时序 2.USART简介 3.配置USART基本结构 4.初始化模板 (1) 接收一个数据 (2) 发送一个数据 一、USART串口 1.串口参数及时序 波特率:串口通信的速率起始位:标志一个数据帧的开始&#xff0c;固定为低电平数据位:数据帧的有效载荷&#…

黑马Day01-03集开始

03集 JSX jsx里面可以写 表达式,表达式里面会返回一个值js语法的扩展,需要babel解析才能够在浏览器运行 语法 使用花括号 {} ,在里面进行编写jsx代码04集 高频场景 使用引号传递字符串 使用js变量 函数调用和方法调用 使用js对象.js自带的一些对象或new出来的对象{&quo…

vue 路由学习

params 不能传递对象类型如 [ ]和{ } query传参 总结&#xff1a; query传参既可以通过name 和path 找到路由规则里的组件&#xff0c;所以为了统一避免非必要麻烦 无论是使用query传参还是 params传参 映射路由建议统一使用 name 进阶 props的使用 备注&#xff1a;资料来自…

JDK安装全攻略:开启Java编程大门

目录 一、安装前准备1.1 确认系统类型1.2 检查系统要求1.3 下载 JDK 安装包 二、Windows 系统下 JDK 安装步骤2.1 双击安装包2.2 选择安装目录2.3 完成安装 三、Windows 系统环境变量配置3.1 打开环境变量设置3.2 配置 JAVA_HOME 变量3.3 配置 Path 变量3.4 验证配置 四、Linux…

《P1253 扶苏的问题》

题目描述 给定一个长度为 n 的序列 a&#xff0c;要求支持如下三个操作&#xff1a; 给定区间 [l,r]&#xff0c;将区间内每个数都修改为 x。给定区间 [l,r]&#xff0c;将区间内每个数都加上 x。给定区间 [l,r]&#xff0c;求区间内的最大值。 输入格式 第一行是两个整数&…

09.【C语言学习笔记】指针(一)

目录 1. 内存和地址 1.1 内存 1.2 究竟该如何理解编址 2. 指针变量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指针变量和解引用操作符&#xff08;*&#xff09; 2.2.1 指针变量 2.2.2 如何拆解指针类型 2.2.3 解引用操作符 * 2.3 指针变量的大小…

Java中static关键字的作用与使用详解

static是Java中一个非常重要的关键字&#xff0c;它可以用来修饰变量、方法、代码块和嵌套类。下面将从多个方面详细解释static的作用和使用方法。 一、static变量&#xff08;类变量&#xff09; 作用 static变量属于类&#xff0c;而不是类的某个实例。所有实例共享同一个s…

HMLDM-UD100A 型工业激光测距仪通过modbusRTU 转 profinet 网关轻松接入到西门子1200plc

HMLDM-UD100A 型工业激光测距仪通过modbusRTU 转 profinet 网关轻松接入到西门子1200plc 在现代工业生产与自动化控制领域&#xff0c;精准的测量设备与高效的通信技术至关重要。HMLDM-UD100A 型工业激光测距仪凭借其高精度、稳定性强等优势&#xff0c;广泛应用于各类工业场景…

数据结构与算法:图论——深度优先搜索dfs

深度优先搜索dfs 提到深度优先搜索&#xff08;dfs&#xff09;&#xff0c;就不得不说和广度优先搜索&#xff08;bfs&#xff09;有什么区别 根据搜索方式的不同&#xff0c;可以将图的遍历分为「深度优先搜索」和「广度优先搜索」。 深度优先搜索&#xff1a;从某一顶点出…

数组题解——​合并区间【LeetCode】

56. 合并区间 排序&#xff1a; 将所有区间按起始位置 start 从小到大排序。这样&#xff0c;重叠的区间会相邻排列&#xff0c;方便后续合并。 合并&#xff1a; 初始化一个空列表 merged&#xff0c;用于存储合并后的区间。遍历排序后的区间列表&#xff1a; 如果 merged 为…