HOT 100 最难的题居然是游戏厂的最爱

写在前面

翻看 网易 历年笔面题单的时候,发现一道有意思的题目。

该题评论区,网易 的踪影很少,反而被那些在 4399 笔试中遇到的同学所攻陷:

alt
alt

好嘛,所以这道题还是「游戏厂」的最爱?!🤣

进一步细看,大家对这道题的评价,可谓“惨不忍闻”:

alt
alt

但,如果真的是这么难的题。

那不可能没有那两位重量级选手呀,于是乎果然:

字节跳动:国内算法笔试面试天花板
字节跳动:国内算法笔试面试天花板
华为:哎,就是卷
华为:哎,就是卷

这里特别说明一下,上面那位用回溯做出来的同学留言。

回溯属于「爆搜」方案,时间复杂度是指数级别的,必然会 TLE(超时),因此回溯做出来的解法不算通过哈。

我们一起来看看正解是什么。

题目描述

平台:LeetCode

题号:312

n 个气球,编号为 0n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1i + 1 代表和 i 相邻的两个气球的序号。

如果 i - 1i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。

求所能获得硬币的最大数量。

示例 1:

输入:nums = [3,1,5,8]

输出:167

解释:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins =  3*1*5    +   3*5*8   +  1*3*8  + 1*8*1 = 167

示例 2:

输入:nums = [1,5]

输出:10

提示:

区间 DP

定义 为考虑将 范围内(不包含 lr 边界)的气球消耗掉,所能取得的最大价值。

根据题意,我们可以对 nums 进行扩充,将其从长度为 nums 变为长度 arr,其中 对应了原数组 nums,而

此时易知 即是答案,不失一般性考虑 该如何转移,假设在 范围内最后剩下的气球的编号为 ,此时的 由「以 为分割点的两端所产生的价值」和「消耗 本身带来的价值」两部分组成:

为了确保转移能够顺利进行,我们需要确保在计算 的时候,区间长度比其小的 均被计算。

因此我们可以采用先枚举区间长度 len,然后枚举区间左端点 l(同时直接算得区间右端点 r)的方式来做。

Java 代码:

class Solution {
    public int maxCoins(int[] nums) {
        int n = nums.length;
        int[] arr = new int[n + 2];
        arr[0] = arr[n + 1] = 1;
        for (int i = 1; i <= n; i++) arr[i] = nums[i - 1];
        int[][] f = new int[n + 2][n + 2];
        for (int len = 3; len <= n + 2; len++) {
            for (int l = 0; l + len - 1 <= n + 1; l++) {
                int r = l + len - 1;
                for (int k = l + 1; k <= r - 1; k++) {
                    f[l][r] = Math.max(f[l][r], f[l][k] + f[k][r] + arr[l] * arr[k] * arr[r]);
                }
            }
        }
        return f[0][n + 1];
    }
}

C++ 代码:

class Solution {
public:
    int maxCoins(vector<int>& nums) {
        int n = nums.size();
        int arr[n + 2];
        arr[0] = arr[n + 1] = 1;
        for (int i = 1; i <= n; i++) arr[i] = nums[i - 1];
        int f[n + 2][n + 2];
        memset(f, 0sizeof f);
        for (int len = 3; len <= n + 2; len++) {
            for (int l = 0; l + len - 1 <= n + 1; l++) {
                int r = l + len - 1;
                for (int k = l + 1; k <= r - 1; k++) {
                    f[l][r] = max(f[l][r], f[l][k] + f[k][r] + arr[l] * arr[k] * arr[r]);
                }
            }
        }
        return f[0][n + 1];
    }
};

Python 代码:

class Solution:
    def maxCoins(self, nums: List[int]) -> int:
        n = len(nums)
        arr = [1] * (n + 2)
        arr[0] = arr[n + 1] = 1
        for i in range(1, n + 1):
            arr[i] = nums[i - 1]
        f = [[0] * (n + 2for _ in range(n + 2)]
        for clen in range(3, n + 3):
            for l in range(0, n + 2 - clen + 1):
                r = l + clen - 1
                for k in range(l + 1, r):
                    f[l][r] = max(f[l][r], f[l][k] + f[k][r] + arr[l] * arr[k] * arr[r])
        return f[0][n + 1]

TypeScript 代码:

function maxCoins(nums: number[]): number {
    const n = nums.length
    const arr = new Array<number>(n + 2).fill(1)
    for (let i = 1; i <= n; i++) arr[i] = nums[i - 1]
    const f = new Array<Array<number>>(n + 2)
    for (let i = 0; i < n + 2; i++) f[i] = new Array<number>(n + 2).fill(0)
    for (let len = 3; len <= n + 2; len++) {
        for (let l = 0; l + len - 1 <= n + 1; l++) {
            const r = l + len - 1
            for (let k = l + 1; k <= r - 1; k++) {
                f[l][r] = Math.max(f[l][r], f[l][k] + f[k][r] + arr[l] * arr[k] * arr[r])
            }
        }
    }
    return f[0][n + 1]
}
  • 时间复杂度:
  • 空间复杂度:

总结

看到这里,你是否和下面这两位同学感受一样?🤣 (头像太可爱,不打码了

alt
alt

其实,这只是一道经典的「区间 DP」入门变形题。

首次遇到可能觉得有点无从下手,但其实区间类的 DP 问题通常从题面就给予了极大的暗示。

但凡是这种 「回合决策会对当前"左右端点/区间"产生影响,或依赖于当前"左右端点/区间"」 的问题,都可以往「区间 DP」去想。

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/260486.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 常用命令之 fdisk 命令用法介绍

fdisk 是一个用于处理磁盘分区的命令行工具,它在 Linux 系统中广泛使用。fdisk 命令可以创建、删除、更改、复制和显示硬盘分区,以及更改硬盘的分区 ID。 fdisk 命令的常用参数如下 -l:列出所有分区表-b:设置扇区大小,如果不设置,默认为 512 字节-u:改变显示/输入单位-…

亚马逊鲲鹏系统引爆广告点击率提升秘籍

在竞争激烈的电商市场&#xff0c;提高广告点击率成为各大卖家争相追求的目标。而如今&#xff0c;亚马逊鲲鹏系统的强大功能再次为卖家们打开了广告优化的新大门。其中&#xff0c;搜索广告功能更是成为提高关键词排名的利器。本文将详细介绍如何通过亚马逊鲲鹏系统实现点击广…

全球知名的五款JavaScript混淆加密工具详解

​ 现在市场上有很多好用的混淆加密工具&#xff0c;其中一些比较流行且受欢迎的工具包括&#xff1a; 1、UglifyJS&#xff08;罗马尼亚&#xff09;&#xff1a;UglifyJS是一个非常流行的 JavaScript工具库&#xff0c;它可以压缩、混淆、美化和格式化 JavaScript 代码。使用…

A01、关于jvm执行子系统

1、Class 类文件结构 1.1、Java跨平台的基础 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码&#xff08;ByteCode&#xff09;是构成平台无关性的基石&#xff0c;也是语言无关性的基础。Java虚拟机不和包括Java在内的任何语言绑定&#xff0c;它只与 “…

新三板炒股开户需要满足哪些条件?交易规则有哪些?

新三板是全国中小企业股份转让系统&#xff0c;属于场外市场&#xff0c;不能满足在主板上市的中小企业就可以申请在新三板挂牌交易。 一、新三板开通条件 新三板分为2个层级&#xff1a; 创新层&#xff1a;开通前10个交易日日均资产100万及以上&#xff0c;两年的股票交易经…

Jenkins 构建触发器指南

目录 触发远程构建 (例如&#xff0c;使用脚本) 描述 配置步骤 安全令牌 在其他项目构建完成后触发构建 描述 配置步骤 定时触发构建 描述 配置步骤 GitHub钩子触发GITScm轮询 描述 配置步骤 Poll SCM - 轮询版本控制系统 描述 触发远程构建 (例如&#xff0c;使…

基于SSM的双减后初小教育课外学习生活活动平台的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

基于EasyDarwin、ffmpeg实现rtsp推流

目录 1 安装EasyDarwin 2 编译安装ffmpeg 3 启动EasyDarwin 4 ffmepg推流 5 百度网盘备份 某项目中测试时需要用到推流&#xff0c;于是用EasyDarwin、ffmpeg实现了RTSP推流&#xff0c;简单记录下过程&#xff0c; 1 安装EasyDarwin 这个可以去官网下载&#xff1a;Eas…

SearchWP WordPress高级网站内容搜索插件

点击阅读SearchWP WordPress高级网站内容搜索插件原文 SearchWP WordPress高级网站内容搜索插件是一个非常强大的工具&#xff0c;可以显着增强您网站的搜索功能。通过向网站访问者提供高度相关和精确的搜索结果&#xff0c;它可以有效地简化他们的搜索过程&#xff0c;促进发…

快速能访问服务器的文件

1、背景 访问ubuntu上的文件 2、方法 python3 -m http.server 8081 --directory /home/ NAS 共享访问协议 — NFS、SMB、FTP、WebDAV 各有何优势&#xff1f;http://1 Ubuntu 搭建文件服务器&#xff08;Nginx&#xff09;

SCA面面观 | SCA关键技术深度解析

数字时代的软件开发普遍遵循敏捷实践&#xff0c;发布和部署周期都很短&#xff0c;开发团队非常依赖开源来加速创新迭代速度。因此&#xff0c;对团队项目中包含的每个开源组件进行跟踪非常重要&#xff0c;可以避免法律风险&#xff0c;保持强大的安全态势。 在DevSecOps环境…

[c]用指针进行四个数排序

#include<stdio.h> void swap(int*p1,int*p2)//定义函数&#xff0c;实现两个数值交换 {int temp;temp*p1;*p1*p2;*p2temp; } void psort( int *pa, int *pb,int *pc,int *pd) {int i1;for(i1;i<3;i)//对四个数排序&#xff0c;至少3次循环&#xff0c;交换过后是升序…

Observability:客户为什么选择 Elastic 做日志?

作者&#xff1a;Ty Bekiares Elastic 正在改变日志体验以满足现代工作流程的需求。 在没有其他可观察信号的情况下&#xff0c;通常基础设施中的所有内容&#xff08;硬件、软件和服务&#xff09;都会发出日志行。 然而&#xff0c;日志通常是根据开发人员的想法构建的&…

大模型互相“薅羊毛”背后,行业基本操作,规范化势在必行

最近&#xff0c;字节跳动被曝调用 OpenAI API 接口训练大模型的争议&#xff0c;以及谷歌大模型 Gemini 被曝使用百度文心一言进行中文语料训练等事件&#xff0c;在行业里引发了不小的关注和讨论。 不明真相的网友们一边热情吃瓜&#xff0c;一边也在感叹 AI 大厂之间互相“…

简单易懂!Pytorch安装教程(超详细)

在正式开始学习Pytorch之前&#xff0c;安装Pytorch同样是重要的一个环节。我将安装Pytorch的主要过程以及遇到的一些问题写在下面&#xff0c;希望能对各位有所帮助。 一、系统与环境说明 在开始用Pytorch进行深度学习之前&#xff0c;要先准备好基本的软硬件环境。下面我分…

深入理解网络 I/O:FileOutputStream、BufferFileOutputStream、ByteBuffer

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…

怎么选择高压放大器(高压放大器选型指南)

在许多科学、工程和实验应用中&#xff0c;需要对高压信号进行放大&#xff0c;以便进行测量、激励或其他各种目的。选择适当的高压放大器对于系统性能至关重要。下面将带来高压放大器选型指南的介绍&#xff0c;帮助工程师们在众多选项中做出明智的选择。 1.确定应用需求 首先…

规则引擎调研情况 URule Pro、VRS和ILOG ODM

最近调研了三家公司的规则引擎产品&#xff0c;各有利弊&#xff0c;具体情况如下&#xff1a; 1. URule Pro 配置本地环境&#xff1a; Web端测试样例&#xff1a; 产品特点&#xff1a; 编程语言 Java语言 是否有Python接口 否 核心算法 3.0及之前的版本 Rete算法…

应用 Strangler 模式将遗留系统分解为微服务

许多来源在一般情况下提供了微服务的解释&#xff0c;但缺乏特定领域的示例。新来者或不确定从哪里开始的人可能会发现掌握如何将遗留系统过渡到微服务架构具有挑战性。本指南主要面向那些正在努力启动迁移工作的个人&#xff0c;它提供了特定于业务的示例来帮助理解该过程。 …

还在用nvm?来试试更快的node版本管理工具——fnm

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热衷分享有趣实用的文章&#xff0c;希望大家多多支持&#xff0c;一起进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 目录 什么是node版本管理 常见的node版本管理工具 fnm是什么 安装fnm …