news 2026/8/8 8:33:31

Python+Appium 2移动自动化测试:从环境搭建到脚本实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python+Appium 2移动自动化测试:从环境搭建到脚本实战

1. 项目概述:为什么是Python+Appium?

如果你正在为移动应用(无论是Android还是iOS)的回归测试、兼容性测试或者日常的冒烟测试感到头疼,每次版本更新都要手动点点点,那Python+Appium这套组合拳,绝对是你工具箱里不可或缺的利器。我这些年带过不少测试团队,从零开始搭建自动化框架,Appium几乎是绕不开的选择,而Python以其简洁的语法和丰富的生态,让它俩成了黄金搭档。

简单来说,Appium是一个开源的、跨平台的移动应用自动化测试框架。它的核心魅力在于“一次编写,到处运行”——你用同一套测试脚本,理论上可以测试Android和iOS应用。而Python,作为脚本语言里的“瑞士军刀”,写起测试用例来又快又清晰,特别适合测试工程师快速上手和构建复杂的测试逻辑。市面上那些所谓的“AI自动化测试”或者“自动化测试平台”,底层很多也是基于这些开源技术做的封装。所以,直接掌握这套原生组合,不仅能解决眼前的问题,更能让你理解自动化测试的底层逻辑,未来无论面对什么工具都能游刃有余。

这篇文章,我会以一个从业超过十年的老测试的身份,带你从零开始,手把手拆解如何用Python和Appium搭建一个可用的、健壮的自动化测试环境,并完成一个完整的测试用例。我会重点讲清楚每个步骤“为什么”要这么做,以及我在实际项目中踩过的那些“坑”,确保你拿到的是能直接上手的“干货”,而不是一堆零散的官方文档翻译。

2. 环境搭建与配置避坑指南

环境搭建是劝退新手的第一个门槛,网上教程很多,但往往忽略了版本兼容性和环境变量这些魔鬼细节。我会以Windows/macOS双平台为例,把每一步的原理和注意事项讲透。

2.1 Python环境:别只盯着安装包

很多新手卡在第一步:Python安装。他们从官网下载了安装包,一路下一步,然后在命令行里输入python,发现要么提示“不是内部命令”,要么调出来的是系统自带的旧版本。

核心原因在于环境变量(PATH)。安装程序通常有个“Add Python to PATH”的选项,一定要勾选。如果忘了勾选,或者安装后依然不行,就需要手动配置。

对于Windows用户

  1. 右键点击“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”。
  2. 在“系统变量”或“用户变量”中找到Path变量,点击“编辑”。
  3. 添加两条路径(具体路径根据你的Python安装位置调整,通常类似):
    • C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\(Python解释器主目录)
    • C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\Scripts\(pip等工具目录)
  4. 打开新的命令行窗口,输入python --versionpip --version验证。

对于macOS/Linux用户: 通常更推荐使用Homebrew来安装和管理Python,能避免很多权限和路径问题。安装Homebrew后,只需执行brew install python即可。系统会自动处理好路径。

注意:强烈建议使用Python 3.7及以上版本,并且避免使用中文用户名路径安装Python,某些依赖库在包含中文的路径下可能会编译失败。

虚拟环境是专业操作的起点:永远不要直接在系统Python环境里安装项目依赖。使用venv创建隔离环境是必须的。

# 在你的项目目录下 python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate

激活后,命令行提示符前会出现(venv)字样。之后所有pip install操作都只影响这个虚拟环境,项目迁移和依赖管理会清晰无数倍。

2.2 Node.js与Appium 2的安装逻辑

Appium 2 是一个巨大的架构改进。Appium 1.x 是一个巨大的单体包,而 Appium 2 变成了一个核心驱动(appium)加各种插件(driver,plugin)的模式。这带来了更好的灵活性和可维护性,但安装步骤也稍有变化。

首先需要安装Node.js,因为Appium是基于Node.js运行的。去Node.js官网下载LTS(长期支持)版本安装即可。安装后,在命令行用node -vnpm -v检查。

然后安装Appium 2

npm install -g appium

安装完成后,用appium -v检查版本。你可能会看到类似3.5.2这样的版本号,这是Appium 2的版本系列。

最关键的一步:安装驱动(Driver)。Appium 2 核心本身不包含任何设备驱动,你需要按需安装。对于Android测试,必须安装uiautomator2驱动(这是目前Android主流和稳定的选择);对于iOS测试,则需要安装xcuitest驱动。

# 安装Android驱动 appium driver install uiautomator2 # 安装iOS驱动(如果在macOS上) appium driver install xcuitest

你可以通过appium driver list来查看已安装的驱动。这一步是很多新手运行脚本时报“No driver found”错误的根源。

2.3 客户端库与IDE准备

安装Python客户端库:在激活的虚拟环境中,安装Appium的Python客户端。

pip install Appium-Python-Client

请注意,Appium 2 对应的是Appium-Python-Client的 2.x 或更高版本,它与Selenium 4兼容。所以通常你会同时安装:

pip install Appium-Python-Client selenium

版本兼容性很重要,老教程可能让你装旧版本,会导致新特性无法使用。

IDE的选择:VS Code是当前非常流行的选择,轻量且插件丰富。你需要安装Python扩展和Pylance。配置Python解释器路径指向你的虚拟环境中的python.exe(Windows)或python(macOS)即可。PyCharm是另一个强大的专业IDE,对Python项目管理和调试支持更完善,社区版就足够测试开发使用。根据个人习惯选择即可。

2.4 移动端环境准备(以Android为例)

  1. 开启开发者选项与USB调试:在手机“设置”-“关于手机”里,连续点击“版本号”7次,开启开发者模式。然后在开发者选项中,开启“USB调试”。
  2. 安装Android SDK Platform-Tools:这不是完整的Android Studio,而是包含adb(Android调试桥)等关键工具的精简包。去Android开发者官网下载,解压后将其platform-tools文件夹路径添加到系统的PATH环境变量中。
  3. 连接电脑:用USB线连接手机,在命令行输入adb devices。如果看到设备序列号并显示device,说明连接成功。如果显示unauthorized,需要在手机弹出的“允许USB调试”对话框中点击确认。

至此,一个完整的Python+Appium 2自动化测试基础环境就搭建好了。这个过程看似步骤繁多,但每一步都有其必要性,理解后就能举一反三。

3. 核心概念与Desired Capabilities解析

环境好了,我们来聊聊写脚本前必须吃透的核心——Desired Capabilities。你可以把它理解成发给Appium服务器的“一份订单”,告诉它:“嗨,我需要你这样一台设备,打开这个应用,用这种方式来测试。”

3.1 Desired Capabilities是什么?

它本质上是一个JSON对象,在Python里我们用字典(dict)来表示。里面定义了自动化会话的所有必需参数。没有它,Appium就不知道你要测什么、怎么测。

一个最基础的Android配置示例:

from appium import webdriver desired_caps = { “platformName”: “Android”, # 平台,必须是Android或iOS “platformVersion”: “13”, # 手机系统版本,尽量准确 “deviceName”: “Pixel_5”, # 设备名,自定义,用于日志标识 “appPackage”: “com.example.myapp”, # 被测App的包名 “appActivity”: “.MainActivity”, # 被测App的启动Activity名 “automationName”: “UiAutomator2”, # 自动化引擎,必须和安装的driver对应 “noReset”: True, # 是否在会话开始前重置App状态(如不清缓存) “unicodeKeyboard”: True, # 启用Unicode键盘,支持输入中文等 “resetKeyboard”: True, # 测试结束后重置键盘为原始状态 }

每一对键值都有其特定作用。platformName,deviceName,automationName是必填项。appPackageappActivity用于指定被测应用。

实操心得deviceName并不需要和手机真实型号完全一致,它只是一个逻辑名称。但platformVersion尽量写对,某些控件定位方式可能因系统版本而异。获取包名和Activity最准确的方法是用adb命令:先打开你的App,然后执行adb shell dumpsys window | findstr mCurrentFocus(Windows)或adb shell dumpsys window | grep mCurrentFocus(macOS/Linux)。

3.2 关键Capability参数深度解读

  • automationName:这是Appium 2里至关重要的配置。你必须指定一个已安装的驱动名,如UiAutomator2(Android)或XCUITest(iOS)。如果没装或写错,Appium服务器会直接报错。
  • noResetfullReset
    • noReset: True:不重置应用数据。适合测试连续场景,比如你不想每次测试都重新登录。
    • fullReset: True:完整重置。会在会话开始前卸载应用,结束后再安装。非常干净,但耗时。
    • 两者都设为False(默认):每次会话后会清除应用数据,但不会卸载。这是最常用的折中方案。
  • newCommandTimeout:命令超时时间(秒)。如果Appium服务器在这段时间内没收到任何新命令,会自动结束会话。对于调试或复杂操作,可以设大一点,比如600
  • udid:当电脑连接了多台设备时,必须用这个参数指定具体哪台设备。通过adb devices命令可以获取设备的UDID。

理解并合理配置这些Capabilities,是写出稳定脚本的基础。很多“脚本跑着跑着就断了”或者“环境不对”的问题,根源都在这里。

4. 第一个自动化测试脚本实战

理论说得再多,不如动手写一个。我们来创建一个完整的测试脚本,目标是打开手机上的“设置”应用(因为它每个手机都有),点击“关于手机”选项。

4.1 脚本结构与启动会话

首先,我们导入必要的模块,配置Capabilities,并初始化驱动。

from appium import webdriver from appium.webdriver.common.appiumby import AppiumBy # 推荐使用AppiumBy进行元素定位 import time # 1. 定义Desired Capabilities desired_caps = { “platformName”: “Android”, “platformVersion”: “13”, # 请修改为你的手机系统版本 “deviceName”: “Android Emulator”, # 可以是任意名称 “automationName”: “UiAutomator2”, “appPackage”: “com.android.settings”, # 系统设置的应用包名 “appActivity”: “.Settings”, # 系统设置的主Activity “noReset”: True, # 避免每次重置设置 “newCommandTimeout”: 300, } # 2. 指定Appium服务器地址并创建驱动实例 # 默认情况下,Appium服务器运行在本地的4723端口 driver = webdriver.Remote(‘http://localhost:4723‘, desired_caps) # 等待几秒让应用完全启动 time.sleep(3)

关键点webdriver.Remote是建立连接的核心。它告诉Python客户端去连接运行在http://localhost:4723的Appium服务,并把我们的“订单”(desired_caps)发过去。Appium服务会根据这个“订单”去操作手机。

4.2 元素定位与交互操作

Appium继承了Selenium的定位策略,并增加了一些移动端特有的方式。最常用的是通过“资源ID”、“XPath”、“文本”和“无障碍功能(Accessibility ID)”来定位。

我们先找到“关于手机”这个条目并点击。不同手机设置菜单的布局可能略有不同,这里以原生Android为例。

# 方法1:通过文本内容定位(如果元素有唯一的文本) try: about_phone = driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, ‘new UiSelector().text(“关于手机”)‘) about_phone.click() except: # 方法2:如果文本不唯一或被翻译,可以尝试用XPath # 这是一个示例XPath,实际需要根据你的手机UI调整 about_phone = driver.find_element(AppiumBy.XPATH, ‘//android.widget.TextView[@text=“关于手机”]‘) about_phone.click() time.sleep(2) # 等待页面跳转

解释一下

  • AppiumBy.ANDROID_UIAUTOMATOR是Android特有的定位方式,使用UiAutomator的API,UiSelector().text()是其中通过文本查找的方法。
  • AppiumBy.XPATH是更强大但也更复杂的定位方式,可以遍历整个页面元素树。上面的XPath意思是:查找一个TextView控件,且其text属性等于“关于手机”。
  • 所有操作后加一个短暂的sleep是个好习惯,给页面加载留出时间,但这不是最佳实践,后面我们会讲更优雅的“等待”。

4.3 获取页面信息与断言

点击进入“关于手机”后,我们可以获取一些文本来验证是否成功。

# 获取页面上的所有文本内容(用于调试或查找关键信息) page_source = driver.page_source # 在实际测试中,我们更倾向于定位特定元素进行断言 # 假设我们想验证“型号”这一行信息存在 # 先找到“型号”标签,再找到它相邻的值(这需要具体分析页面结构,这里仅为示例逻辑) try: model_label = driver.find_element(AppiumBy.XPATH, ‘//*[contains(@text, “型号”)]‘) print(f“找到设备型号标签: {model_label.text}“) # 更复杂的操作可以是获取其兄弟节点的文本作为型号值 except Exception as e: print(f“未找到型号信息: {e}“) # 一个简单的断言示例(使用Python内置的assert) # 假设我们成功进入了关于手机页面,页面标题应该包含‘关于’ title_element = driver.find_element(AppiumBy.CLASS_NAME, ‘android.widget.TextView‘) assert ‘关于‘ in title_element.text, “未成功进入关于手机页面” print(“测试步骤:进入‘关于手机’页面成功”)

4.4 会话清理与退出

测试结束后,必须妥善关闭会话,释放手机资源。

# 等待几秒查看结果 time.sleep(3) # 退出并关闭会话 driver.quit()

重要:一定要调用driver.quit(),而不是driver.close()quit()会关闭整个驱动会话,断开与Appium服务器和设备的连接;而close()在移动端测试中行为可能不确定,通常只关闭当前窗口(不适用于原生App)。

将以上所有代码块按顺序组合到一个.py文件中,在启动Appium服务器(在命令行输入appium)并连接好手机后,运行这个Python脚本,你就能看到手机自动打开设置并点击关于手机了。这就是你的第一个自动化测试脚本!

5. 进阶技巧:让脚本更健壮与可维护

能跑起来只是第一步,写出能在项目中稳定运行、易于维护的脚本才是真正的挑战。

5.1 智能等待:告别time.sleep

在脚本里到处写time.sleep(5)是初级做法,它让测试变得缓慢且不可靠(网络或设备慢时5秒可能不够,快时又浪费等待时间)。Appium提供了两种智能等待:

  1. 隐式等待(Implicit Wait):在创建驱动后设置一次,对整个驱动生命周期有效。它告诉驱动在查找元素时,如果立即没找到,可以轮询等待一段时间。

    driver.implicitly_wait(10) # 单位:秒

    设置了隐式等待后,像find_element这样的操作,如果没立刻找到元素,会最多等待10秒,期间每隔一段时间重试,找到了就继续,超时就抛异常。

  2. 显式等待(Explicit Wait):更灵活、更推荐的方式。针对某个特定条件进行等待,条件满足则继续,超时则报错。需要配合WebDriverWaitexpected_conditions使用。

    from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待“关于手机”这个元素出现,最多等15秒 wait = WebDriverWait(driver, 15) about_phone = wait.until( EC.presence_of_element_located((AppiumBy.ANDROID_UIAUTOMATOR, ‘new UiSelector().text(“关于手机”)‘)) ) about_phone.click()

    显式等待的优势:精准控制,只在需要的地方等待,条件多样(元素可点击、元素可见、文本出现等)。这能极大提升脚本执行速度和稳定性。

5.2 页面对象模型(Page Object Model, POM)

这是UI自动化测试中最核心的设计模式。它的思想是将每个页面(或页面片段)封装成一个类,页面的元素定位符和操作这个页面的方法都封装在这个类里。测试用例则通过调用这些页面对象的方法来完成操作。

好处

  • 高可维护性:当页面UI变动时,你只需要修改对应页面对象类中的元素定位符,所有用到这个元素的测试用例都自动生效。
  • 高可读性:测试用例读起来就像业务文档:“登录页面.输入用户名().输入密码().点击登录()”。
  • 低冗余:避免了在测试脚本中到处散落着重复的元素定位代码。

一个简单的POM示例

# base_page.py - 基础页面类,封装公共方法 class BasePage: def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def find_element(self, by, locator): return self.wait.until(EC.presence_of_element_located((by, locator))) # settings_page.py - 设置页面对象 class SettingsPage(BasePage): # 元素定位符 SEARCH_BAR = (AppiumBy.ID, “com.android.settings:id/search_action_bar”) ABOUT_PHONE_MENU = (AppiumBy.ANDROID_UIAUTOMATOR, ‘text(“关于手机”)‘) def click_about_phone(self): about_elem = self.find_element(*self.ABOUT_PHONE_MENU) # *用于解包元组 about_elem.click() return AboutPhonePage(self.driver) # 返回下一个页面对象 # about_phone_page.py - 关于手机页面对象 class AboutPhonePage(BasePage): MODEL_INFO = (AppiumBy.XPATH, “//*[contains(@text, ‘型号’)]/../android.widget.TextView[2]“) def get_model_number(self): model_elem = self.find_element(*self.MODEL_INFO) return model_elem.text # test_case.py - 测试用例 def test_about_phone_info(): driver = webdriver.Remote(‘http://localhost:4723‘, desired_caps) settings_page = SettingsPage(driver) about_page = settings_page.click_about_phone() model = about_page.get_model_number() print(f“设备型号是: {model}“) assert model is not None driver.quit()

虽然初期搭建POM结构需要多一些设计,但对于长期维护和团队协作来说,收益巨大。

5.3 异常处理与日志记录

自动化脚本运行在复杂的环境中,网络波动、应用卡顿、弹窗干扰都可能导致失败。良好的异常处理和日志能帮你快速定位问题。

import logging from selenium.common.exceptions import NoSuchElementException, TimeoutException # 配置日志 logging.basicConfig(level=logging.INFO, format=‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘) logger = logging.getLogger(__name__) def safe_click(element_locator): “”“一个安全的点击函数,包含重试机制”“” max_retries = 3 for attempt in range(max_retries): try: element = WebDriverWait(driver, 10).until( EC.element_to_be_clickable(element_locator) ) element.click() logger.info(f“成功点击元素: {element_locator}“) return True except (NoSuchElementException, TimeoutException) as e: logger.warning(f“第{attempt+1}次点击尝试失败: {e}“) if attempt == max_retries - 1: logger.error(f“元素{element_locator}点击失败,已达最大重试次数”) # 这里可以附加截图操作 # driver.save_screenshot(‘click_failed.png‘) raise time.sleep(2) # 等待2秒后重试 return False

在关键操作步骤前后添加logger.info记录,在捕获异常时使用logger.error并保存截图(driver.save_screenshot(‘error.png’)),这些信息是后期分析测试失败原因的黄金资料。

6. 常见问题排查与实战心得

即使按照教程一步步来,你也一定会遇到各种问题。这里我总结了一些最高频的“坑”和解决办法。

6.1 连接类问题

  • 问题adb devices列表为空,或设备状态为unauthorized
    • 排查:检查USB线是否完好、USB调试是否开启、电脑是否安装了正确的手机驱动(Windows上常见)。尝试重启adb服务:adb kill-server然后adb start-server。手机上确认弹出的“允许USB调试”对话框。
  • 问题:运行脚本时报错,提示无法连接到http://localhost:4723
    • 排查:确认Appium服务器是否已经启动。在命令行输入appium后,应该看到服务器日志输出,并提示listening on 0.0.0.0:4723。检查是否有其他进程占用了4723端口。

6.2 会话启动类问题

  • 问题session not created: Could not find a driver for...
    • 排查:这是Appium 2的典型问题。确认desired_caps中的automationName是否正确(如UiAutomator2)。并通过appium driver list确认该驱动已安装。如果没有,使用appium driver install命令安装。
  • 问题An unknown server-side error occurred while processing the command. Original error: Cannot start the ‘com.example.app‘ application...
    • 排查:首先检查appPackageappActivity名称是否完全正确。对于非系统应用,确保APK已经安装到设备上(可以用adb install安装)。有时需要指定APK的绝对路径,使用app这个capability:“app”: “/path/to/your/app.apk“

6.3 元素定位与交互类问题

  • 问题:脚本报错NoSuchElementException,但用Appium Inspector(一个元素检查工具)明明能看到这个元素。
    • 排查
      1. 等待问题:最常见。元素还没加载出来脚本就去找了。务必使用显式等待(WebDriverWait)。
      2. 上下文问题:混合应用(Hybrid App)或WebView中,需要先用driver.switch_to.context(‘WEBVIEW_‘)切换到WebView上下文才能定位网页元素。
      3. 定位符问题:页面可能有多个相同属性的元素,你的定位符不够唯一。尝试使用更精确的XPath,或者结合多个属性定位,如//android.widget.Button[@text=“确定” and @resource-id=“ok_btn”]
      4. 动态内容:元素的resource-idtext可能是动态生成的。尝试使用containsstarts-with等XPath函数进行模糊匹配。
  • 问题Element is not clickable at point... Another element would receive the click
    • 排查:元素被遮挡(如弹窗、蒙层)。先处理掉遮挡物(关闭弹窗),或者尝试用driver.execute_script(‘mobile: scroll‘, {‘direction‘: ‘down‘})(Appium特有命令)滚动到元素可见区域,再尝试点击。也可以使用element.click()的替代方案:driver.execute_script(‘arguments[0].click();‘, element)(通过JavaScript直接点击)。

6.4 性能与稳定性问题

  • 问题:脚本运行速度慢,不稳定,时好时坏。
    • 优化方向
      1. 减少不必要的等待:用显式等待替代固定的sleep
      2. 优化定位符:优先使用IDaccessibility id,它们通常最快。XPath遍历较慢,尽量避免//开头的全局搜索。
      3. 避免重复查找:对同一个元素,找到后存储到变量里重复使用,不要每次操作都重新查找。
      4. 设备状态:关闭不必要的后台应用,保证手机有足够的内存和电量。在稳定的网络环境下运行。
      5. 升级版本:确保Appium Server、客户端库、驱动都是较新的稳定版本。

自动化测试不是一蹴而就的,它是一个不断调试、优化和积累经验的过程。每次遇到问题并解决它,你对整个系统的理解就会加深一层。从搭建环境到写出第一个脚本,再到用POM设计模式组织代码,最后能从容处理各种异常,这个过程本身就是一个测试工程师成长的缩影。记住,核心价值不在于自动化了多少用例,而在于通过自动化,你更深刻地理解了你的应用,并建立了一套快速反馈质量的可靠机制。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/8 8:33:08

SSM+Vue家庭菜谱系统开发与毕业设计实践

1. 项目背景与核心需求 2026届计算机相关专业毕业设计选题"SSMVue家庭菜谱软件"是一个典型的Web应用开发项目,它结合了后端SSM框架和前端Vue.js技术栈。这类选题在当前高校计算机专业中非常普遍,因为它既涵盖了企业级开发的主流技术&#xff0…

作者头像 李华
网站建设 2026/8/8 8:31:52

【AI大模型】约束提示:给模型加边界条件的设计方法

【AI大模型】约束提示:给模型加边界条件的设计方法(含实操代码) 在AI大模型规模化落地应用中,绝大多数输出失控、内容冗余、答非所问、越界跑偏、合规违规的核心原因,并非模型能力不足,而是提示词无边界、任务无约束、输出无限制。大模型具备极强的泛化生成能力,在无明…

作者头像 李华
网站建设 2026/8/8 8:30:56

3分钟搞定戴尔G15散热控制:告别AWCC臃肿软件的终极方案

3分钟搞定戴尔G15散热控制:告别AWCC臃肿软件的终极方案 【免费下载链接】tcc-g15 Thermal Control Center for Dell G15 - open source alternative to AWCC 项目地址: https://gitcode.com/gh_mirrors/tc/tcc-g15 还在为戴尔G15笔记本散热问题头疼吗&#x…

作者头像 李华
网站建设 2026/8/8 8:29:58

深入解析CAN通信矩阵:从信号属性到工程实践

1. 项目概述:从“黑盒”到“白盒”的CAN通信认知跃迁在汽车电子、工业控制这些领域里混久了,你肯定对CAN总线不陌生。它就像设备之间的“神经系统”,负责传递各种控制指令和状态信息。但很多工程师,尤其是刚入行的朋友&#xff0c…

作者头像 李华
网站建设 2026/8/8 8:29:18

Kimi LeetCode 3836. 恰好 K 个下标对的最大得分 TypeScript实现

以下是 LeetCode 3836. 恰好 K 个下标对的最大得分 的 TypeScript 实现。解题思路三维动态规划。定义 dp[i][j][k] 为:在 nums1 的前 i 个元素和 nums2 的前 j 个元素中,恰好选择 k 对下标所能获得的最大得分。状态转移有三种情况: 1. 跳过 n…

作者头像 李华