LeetCode——Weekly Contest 320(附动态规划解题思路)

news2024/12/26 0:53:18

LeetCode周赛第320场记录

质量还不错的一场周赛,也可以学到不少知识。

2475. 数组中不等三元组的数目(排序+荷兰国旗问题)

在这里插入图片描述
这道题非常简单,就是从头向后一一找出不含重复数字的三元组。我在比赛时直接写了一个三重循环暴力来解,这道题的数据规模是 1 0 2 10^2 102,因此 O ( n 3 ) O(n^3) O(n3)的复杂度是可以安全过的,但是暴力法不是最优解

以下是暴力枚举的代码:

class Solution {
public:
    int unequalTriplets(vector<int>& nums) {
        int Ans = 0, n = nums.size();
		for(int i = 0 ; i < n ; ++i)
			for(int j = i + 1 ; j < n ; ++j)
				if(nums[i] != nums[j])
					for(int k = j + 1 ; k < n ; ++k)
						if(nums[k] != nums[i] && nums[k] != nums[j])
							++Ans;		
		return Ans;
    }
};

这道题还可以使用类似于荷兰国旗问题的思路来求解,因为三个数字的绝对数值不重要,所以对于每个特定数字而言,其对于答案的贡献是:

比它小的数字个数 × \times × 自身个数 × \times × 比它大的数字个数

可见整个区间又被分为了三个部分:

1.[0, Left)区间表示比它小的元素区间

2.[Left, i)表示当前元素的区间

3.[i, n)表示比当前元素大的区间

注意为了统一,我统统使用左闭右开区间来进行区间表示,这样写出的代码如下:

这种算法的思维难度还是不低的,时间复杂度也降低至 O ( n log ⁡ n ) O(n\log{n}) O(nlogn)(排序算法复杂度)。

int unequalTriplets(vector<int>& nums) {
        int Ans = 0;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        int Left = 0;
        for(int i = 1 ; i < n  ; ++i)
            if(nums[i] != nums[i - 1])
            {
                Ans += Left * (i - Left) * (n - i);
                Left = i ;
            }
        return Ans;
    }

2476. 二叉搜索树最近节点查询(中序遍历+二分)

在这里插入图片描述
见到二叉搜索树一定要想到性质:中序遍历有序

在比赛时做这道题,我一开始还是在使用传统的递归算法来处理,写完之后发现会超时,于是更换思路到中序遍历。第二个思路就是理所当然的将二叉搜索树进行中序遍历,但是遇到二叉搜索树应该第一次就想到这种做法,因为它直接将树的问题转化为了线性序列问题

对上述二叉搜索树进行中序遍历之后,就可以按照题意来找Min和Max了,这里可以使用二分查找来找到这个数字,C++ STL里的lower_bound和upper_bound函数可以很好地完成这个任务,但是这个地方的逻辑也比较微妙,处理不好很容易犯错,下面给出代码:

class Solution {
	vector<int> InOrder{};
	void DFS(TreeNode* root)
	{
		if(root)
		{
			DFS(root->left);
			InOrder.push_back(root->val);
			DFS(root->right);
		}
	}
public:
    vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {
		vector<vector<int>> Ans;
        DFS(root);                      // 得到二叉搜索树的中序遍历序列
		int n = InOrder.size();         
		for(auto Each : queries)        // O(m)
		{
			auto MinIter = upper_bound(InOrder.begin(), InOrder.end(), Each);   
			auto MaxIter = lower_bound(InOrder.begin(), InOrder.end(), Each);    
			/*
				注意这里的处理逻辑:
				Min要使用upper_bound来找
				Max要使用lower_bound来找
				同时还要判断是否是特殊的迭代器,因为这可能意味着它们没有找到解
			*/
			Ans.push_back({MinIter == InOrder.begin() ? -1 : *(MinIter - 1), MaxIter == InOrder.end() ? -1 : *MaxIter});
		}
		return Ans;

        // complexity : O(n + m * logn)
    }

2477. 到达首都的最少油耗(转化+多叉树的DFS)

在这里插入图片描述
这道题主要考察问题的转化,题目本身不难但是很容易会错意,我一开始想把这道题当成图的单源点最短路径问题,使用Dijkstra算法来解。但这是不对的,因为虽然每条路费一升汽油可以当作边的权重,但是这里还有一个座位seats的限制量我不知道该如何转化。

其实这就是一个简单的多叉树的DFS问题,一辆车载下尽可能多的代表就是最省油的做法,所以对于图中的(多叉树中的)每一个节点而言,将它所连接的孩子节点的代表完全聚合就是最简单的做法,多余的车可以停在父节点处不动,它们并不额外消耗汽油。

所以这个问题转化完成之后就成为了一颗多叉树的遍历问题,从任何一个节点出发,统计它的孩子节点数量到本地完成汇聚之后再通往它的父节点,一层层汇聚上去直到根节点(首都)即可。这里需要注意,树作为一种图的特殊情况,多叉树的遍历也是不需要开辟Visited数组的,因为它们不会有环的出现:

重要知识点,多叉树的遍历不需要开辟Visited的数组(因为无环)

只需要记录下父节点编号,在遍历时剔除掉即可

另外一个需要注意的点是,如何对除法做上取整,这里可以参考这篇博客。

// a,b均为整数,a除以b(上取整)的方法是:
x = (a + b - 1) / b

给出这道题的完整代码如下:

class Solution {
public:
    long long minimumFuelCost(vector<vector<int>>& roads, int seats) {
        int n = roads.size() + 1;

        // 建图
        vector<int> e[n];
        for (auto &road : roads) {
            e[road[0]].push_back(road[1]);
            e[road[1]].push_back(road[0]);
        }

        long long ans = 0;
        // DFS 统计子树大小,同时统计答案, fa是父节点编号,遍历时避开它即可
        function<int(int, int)> dfs = [&](int sn, int fa) {
            int ret = 1;
            for (int fn : e[sn]) if (fn != fa) {
                // 计算 sn -> fn 这条边的贡献
                int t = dfs(fn, sn);
                ans += (t + seats - 1) / seats;
                // 更新子树节点大小
                ret += t;
            }
            return ret;	// 返回结果到上一层
        };
        dfs(0, -1);
        return ans;
    }
};

2478. 完美分割的方案数

在这里插入图片描述

这又是一道动态规划的题目,在bilibili上看了灵茶山艾府的讲解视频,他在视频中讲解了求解动态规划问题的思考方法,这里要简单做个记录。

解决动态规划问题的思考步骤:
Q1.问题中存在哪些变量?
A1.本题中有分割子串的个数k,原字符串的长度n,每个子字符串的最小长度MinLength.

Q2.在上述的基础上复述问题,并且替换变量
A2.把一个长为j的字符串,分割出i段子字符串的合法方案数

Q3.想最后一步发生了什么?(*)
A3.最后一步我们分割出来了一个子字符串,长度为x,且它是原字符串的一个后缀

Q4.去掉最后一步,问题规模缩小了,原问题会变成什么样?
A4.把一个长度为j-x的字符串,分割成i-1段的合法方案数

Q5.得到状态转移方程
A5.从A2中可以得到,f[i][j]表示把字符串s的前j个字符分割成i段的合法方案数
(为什么是”前“j个字符,因为在A3中我们去掉的是原字符串的后缀)
从A4中可以得到,f[i][j] += f[i - 1][j'],其中j'是i-1段的结束下标,因此这里需要枚举j'
j'需要满足一些限制:
	1. j - j' + 1 >= minLength
	2. s[j']是质数,s[j]不是质数

Q6.初始值和答案分别对应于f的什么?
f[0][0] = 1;
Ans = f[k][n] 	

Q7.是否可以优化转移方程?
滚动数组 or others?
本题中j在变大的时候j'也在变大(因为要满足最短长度的限制),所以可以有优化手段->前缀和优化

在完成上述的分析过程之后,下面直接给出本题的代码(copyright:灵茶山艾府):
这道题可以和Weekly Contest318的最小移动总距离一起服用,尝试使用上述的流程来解决之

class Solution {
    const int MOD = 1e9 + 7;

    bool is_prime(char c) {
        return c == '2' || c == '3' || c == '5' || c == '7';
    }

    // 判断是否可以在 j-1 和 j 之间分割(开头和末尾也算)
    bool can_partition(string &s, int j) {
        return j == 0 || j == s.length() || !is_prime(s[j - 1]) && is_prime(s[j]);
    }

public:
    int beautifulPartitions(string &s, int k, int l) {
        int n = s.length();
        if (k * l > n || !is_prime(s[0]) || is_prime(s[n - 1])) // 剪枝
            return 0;
        int f[k + 1][n + 1]; memset(f, 0, sizeof(f));
        f[0][0] = 1;
        for (int i = 1; i <= k; ++i) {
            int sum = 0;
            // 优化:枚举的起点和终点需要给前后的子串预留出足够的长度
            for (int j = i * l; j + (k - i) * l <= n; j++) {
                if (can_partition(s, j - l)) sum = (sum + f[i - 1][j - l]) % MOD; // 这里的j-l可以看成j’,双指针
                if (can_partition(s, j)) f[i][j] = sum;
            }
        }
        return f[k][n];
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebDAV之葫芦儿·派盘+元思笔记

元思笔记 支持webdav方式连接葫芦儿派盘。 卡片笔记不仅是笔记爱好者,学生、医生、投资等各行各业的人都在不约而同的夸赞元思笔记的好。这是一款面向大众的卡片笔记软件,解决了笔记类软件的一个痛点:绝大多数人都很难坚持每天记一点东西。任何笔记工具,不论是纸笔还是电…

时序特征提取工具

在选择了需要提取的特征&#xff0c;确定了时序数据特征提取数据集的长度并对先验知识建模之后&#xff0c;就需要利用工具搭建特征提取系统。科研机构围绕不同问题域搭建的开源时序数据特征提取工具已经不少&#xff0c;我们可以利用这些工具快速实现希望达成的算法效果。下面…

[附源码]Python计算机毕业设计Django的残障人士社交平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

相控阵天线(十):波束跃度、虚位技术、幅度相位误差分析(含代码)

目录简介波束跃度不同移相器位数对方向图的影响不同移相器位数对波束跃度的影响虚位技术不同虚位位数对指向精度的影响不同虚位位数对副瓣电平的影响幅度相位误差分析随机误差周期误差Python代码示例简介 阵列天线的成本、批量和可制造性等实际问题的解决方案的选择直接影响阵…

[msyql]实战:关于回表的一次查询优化实战

起因与前置环境思考与解决方案 第一个理解与方法——分块分页第二个理解与方法——拆分子查询第三个理解与方法——拆分子查询分块分页 原理浅析与总结 回表和索引覆盖的浅解 原理简单说明MYSQL中回表的实现 总结与收获 起因与前置环境 目前在职的公司是已经运转挺久的电商类…

leetcode 343. 整数拆分(动态规划)

题目链接&#xff1a;343. 整数拆分 动态规划 (1) 确定 dpdpdp 数组下标含义&#xff1a; dp[i]dp[i]dp[i]: 将 iii 拆分为至少两个正整数之后的最大乘积&#xff1b; (2) 确定递推公式&#xff1a; 当 i≥2i \ge 2i≥2 时, 设 jjj 是 iii 拆分出来的第一个正整数&#xff0c…

1990-2021年全国30省城镇登记失业率

1、时间&#xff1a;1990-2021年 2、来源&#xff1a;整理自统计NJ 3、数据说明&#xff1a; 包括全国30个省份&#xff0c;不包括西藏&#xff0c;其中北京、天津、辽宁、吉林、江苏、浙江、湖南、四川、新疆2021年数据存在缺失&#xff0c; 内含原始数据&#xff0c;线性…

猿如意开发工具|python3.7

文章目录 一、猿如意是什么&#xff1f;一、猿如意的下载安装使用二、使用猿如意下载安装python3.7总结前言 对于程序猿来说&#xff0c;辅助开发工具箱是非常重要的&#xff0c;可以方便广大的开发者们。今天我就介绍一款非常好用的开发工具箱-猿如意。 一、猿如意是什么&…

大数据必学Java基础(一百零八):过滤器的生命周期

文章目录 过滤器的生命周期 一、构造方法 二、初始化方法 三、拦截请求方法

用R语言实现神经网络预测股票实例

神经网络是一种基于现有数据创建预测的计算系统。最近我们被客户要求撰写关于神经网络的研究报告&#xff0c;包括一些图形和统计输出。 如何构建神经网络&#xff1f; 神经网络包括&#xff1a; 输入层&#xff1a;根据现有数据获取输入的层隐藏层&#xff1a;使用反向传播…

基于PHP+MySQL动漫周边商城销售网站的开发与设计

随着时代的发展,人们对动漫周边产品的关注度越来越高,尤其是对当代的年轻人来说,对一些动漫的手办和玩具等商品都非常的热爱。但是当下时长上的动漫周边产品销售网站还很少,这对钟爱动漫周边产品的来说是一件很痛苦的事情,明明知道一件出现了这些相关产品,但是没有渠道能够购买…

【简单、实用】kubernetes的etcd备份与恢复实现恢复集群配置

学习目标 内容 提示:由于牵涉概念过多,本章主要讲解具体的备份恢复,其他概述 官网:https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/configure-upgrade-etcd/#backing-up-an-etcd-cluster 一. etcd的工作原理 可将其分成两层次:Http层请求、接收消息;剩下的…

家电专用降压DC-DC方案PL8310

PL8310是一个单片36V, 1A降压开关监管机构。PL8310集成了一个36V 250mΩ高侧和一个36V, 140mΩ低侧mosfet提供1A持续负载电流超过4.5V至36V宽工作输入电压带33V输入过电压保护。峰值电流模式控制速度快瞬态响应和逐周电流限制。PL8310具有可配置的线路下降补偿&#xff0c;可配…

CenterNet算法代码剖析

目录 一、图片预处理 1、cv读取原始图片 2、读取图片的中心点 3、计算仿射变化2*3的矩阵 4、基于双线性插值的仿射变化&#xff0c;将原始图片映射到dst图片 5、将原始图片的值归一化到0~1之间 6、使用样本集的mean和std再进行z-score归一化 7、计算特征图的大小&#…

linux mailxdingding机器人报警

前言&#xff1a;采用devops的思想来确认做本文内容目的 作为 <用户角色> 我想要 <结果> 以便于 <目的> 作为运维人员&#xff0c;我想要服务器故障时候能够进行报警&#xff0c;以便于即使处理服务器故障、保障服务器稳定运行 两种方式 邮箱 客户端授权码 …

Kafka - 10 Kafka副本 | 分区副本分配 | 手动调整分区副本 | Leader Partition 负载平衡 | 增加副本因子

文章目录1. 分区副本分配2. 手动调整分区副本3. Leader Partition 负载平衡4. 增加副本因子1. 分区副本分配 如果 kafka 服务器只有 4 个节点&#xff0c;那么设置 kafka 的分区数大于服务器台数&#xff0c;在 kafka底层如何分配存储副本呢&#xff1f; ① 创建 16 分区&…

[附源码]计算机毕业设计springboot高校学生宿舍管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

HashMap(2)-----哈希表

自己实现一个哈希表 class Node { int data;String val;Node next;public Node(int data,String val){ this.valval;this.datadata;} } class myhashtable { Node arr1[];Node headnull;Node tailnull;int count0;private double load0.75;public myhashtable() {this…

ESIM:Enhanced LSTM for Natural Language Inference

原文链接&#xff1a;https://aclanthology.org/P17-1152.pdf 概述 对于自然语言推理任务&#xff0c;Bowman等人在2015年提出了一个大数据集&#xff0c;大多数工作就开始使用神经网络来对该任务进行训练。但作者认为序列模型的潜力还没有完全被挖掘&#xff0c;因此提出了一个…

自建网上商城平台该如何做好运营?

现在很多企业都在自建网上商城系统&#xff0c;但很多都以为建好商城上线就万事大吉了。其实&#xff0c;自建网上商城系统只是一个开始&#xff0c;后期的运营才最重要。如果经营不好&#xff0c;这个商城就白做了&#xff0c;今天小编给大家整理了几个网上商城平台运营方向&a…