对最近的刷题做一个小总结(关于动态规划和贪心)

devtools/2025/3/19 0:16:10/

文章目录

  • 1. 小总结
  • 2. 两道算法
    • 2.1 数组中两个字符串的最小距离
    • 2.2 孩子们的游戏

1. 小总结

最近刷了很多算法题,真正了解到的算法应是dfs,多元dfs,以及动态规划和贪心。

dfs和多元dfs目前并没有真正深入研究过,不过熟悉套路之后,整体的编写还是挺简单的。

对于动态规划,整体的逻辑还是很简单的,难就难在有些题,你看不出来可以用动态规划,比如“约瑟夫环”的问题,而且就算看出来是动态规划,如何确定状态表示,是从这里开始,还是到这里结束,是这两者都可以,还是只有一个可以,这些都是有讲究的,自己还需要再多刷一些动态规划的题目。不过,就我现在的感受而言,动态规划其实跟递推,函数递归等都很类似,本质上都是解决重复子问题。

至于贪心,贪心算法确实是没有那么好get到的,它的原理很简单,关键在于想清楚该怎么“贪”,并且要能够确保这样子“贪”,是正确的,能够从局部最优得到全局最优,这个确定还是比较复杂的。


2. 两道算法

来看一道双指针和一道动态规划的问题。

2.1 数组中两个字符串的最小距离

题目描述:给定给定两个字符串str1和str2,再一个字符串数组strs,返回在strs中str1和str2的最小距离,如果str1或str2为null,或不在strs中,返回-1。
输入描述:输入包含有多行,第一输入一个整数n(1 <= n <= 100000),代表数组strs的长度,第二行有两个字符串分别代表str1和str2,接下来n行,每行一个字符串,代表数组strs(保证题目中出现的所有字符串长度均小于等于10)
输出描述:输出一行,包含一个整数,代表返回的值。
补充说明:时间复杂度O(n),额外空间复杂度O(1)

OJ链接

这道题,是在一个给定的字符数组中,找出两个字符串之间的最小距离。
考虑到,时间复杂度为O(n),所以暴力的O(n ^ 2)遍历肯定是不行的,这题显然应该在给定的原字符数组中用双指针来实现,这样能够满足时空复杂度的要求。

而要想做到使用双指针进行解决,必须找到一定的规律。

在这里插入图片描述
在上图中,如果想要找到两个字符串中的最小距离,有一点是很明确的:对于编号为4的“def”,编号为1的“abc”其实与之相距不可能是最小的,因为前面还有一个编号为2的"def",也就是说,以编号为4的"def"为基准时,另外一个指针没必要从头开始找,而这一点就是本题可以使用双指针的规律所在。

我们代码的整体逻辑就是:

  1. 先找到两个对应的字符串,然后根据下标,确定两个字符串的先后关系。
  2. 靠后的字符串先不动,靠前的字符串接着循环去找下一个与自身相同的字符串,在这个过程中,不断更新距离,直到这个字符串在原先靠后的字符串之后为止。
  3. 继续重复2中的逻辑,直到整个字符数组都被遍历完,跳出循环,此时得到的距离便是两个字符串在整个字符数组中,对应的最小距离。

具体I/O代码如下:

#include <iostream>
#include <vector>
using namespace std;int main()
{ios::sync_with_stdio(false);cin.tie(0);int n;string s1,s2;cin >> n >> s1 >> s2;vector<string> arr;arr.reserve(n);string tmp;while(cin >> tmp){arr.push_back(tmp);}if(s1.empty() || s2.empty())printf("-1");int i = 0,j = 0,sz = arr.size();int distance = INT_MAX;while(i < sz && j < sz){while(i < sz &&  arr[i] != s1)i++;while(j < sz && arr[j] != s2)j++;if(i < sz && j < sz){distance = min(distance,abs(j - i));if(i < j){i++;while(i < sz && arr[i] != s1)i++;}else{j++;while(j < sz && arr[j] != s2)j++:}}}if(distance == INT_MAX)printf("-1");elseprintf("%d",distance);return 0;
}

2.2 孩子们的游戏

每年六一儿童节,牛客都会准备一些小礼物和小游戏去看望孤儿院的孩子们。其中,有个游戏是这样的:首先,让 n 个小朋友们围成一个大圈,小朋友们的编号是0~n-1。然后,随机指定一个数 m ,让编号为0的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0… m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客礼品,请你试着想下,哪个小朋友会得到这份礼品呢?

在这里插入图片描述
要求时间复杂度为O(n),空间复杂度为O(n)。
OJ链接

这是一道非常经典的约瑟夫环问题。

约瑟夫环问题大致有两种解法:

  1. 模拟实现约瑟夫环。使用循环链表可以对约瑟夫环进行很好地模拟,使用数组也可以模拟,不过没有循环链表那么方便,但是模拟的时间复杂度为O(m * n) ,空间复杂度为O(n),在这道题中,通过模拟实现约瑟夫环来解决问题是不合题意的。
  2. 使用动态规划解决约瑟夫环。使用动态规划解决约瑟夫环,寥寥几行代码便可以解决一个较为复杂的问题,是“四两拨千斤”的典范,且时空复杂度满足题意,故使用这种做法。

如何用动态规划解决约瑟夫环。

状态表示:dp[n]表示有n个人,最后留下来的那个人的编号

状态转移方程:这里状态转移方程的确定是一个难点,状态转移方程应为:dp[n] = (dp[n - 1] + m) % n。这里的+m是映射回去时所加,模上一个n是防止加上m之后,编号超过n - 1。

在这里插入图片描述
初始化:此处的动态规划只需用到前面一个的值,因此初始化dp[1]即可,dp[1]显然应该为0.
填表顺序:一维dp,用到前面的值,因此从左往右填表。
返回值:返回dp[n]即可。

不过,由于此题中要求空间复杂度为O(1),因此不能直接用dp表,而使用滚动数组进行空间复杂度的优化。

具体代码如下:

class Solution {
public:int LastRemaining_Solution(int n, int m) {int ret = 0;for(int i = 2;i <= n;i++)ret = (ret + m) % i;return ret;}
};

http://www.ppmy.cn/devtools/168185.html

相关文章

C语言的机器学习

C语言的机器学习 前言 机器学习&#xff0c;是人工智能领域的一个重要分支&#xff0c;它使计算机能够通过经验自动改进性能。在过去的几十年里&#xff0c;机器学习技术得到了广泛的应用&#xff0c;从自然语言处理到计算机视觉&#xff0c;再到推荐系统等&#xff0c;几乎无…

AI驱动的三维创作革命:Claude与Blender深度融合的架构解析与实践路径

一、技术范式创新&#xff1a;从自然语言到三维空间的语义映射 Claude-MCP框架通过多模态语义解析引擎实现了自然语言到三维操作的精准转换&#xff0c;其核心技术突破体现在三个维度&#xff1a; ​抽象概念量化模型 系统内置风格语义向量库&#xff0c;可将"复古风格&q…

结构型模式之桥接模式:解耦抽象和实现

在面向对象设计中&#xff0c;我们经常遇到需要扩展某些功能&#xff0c;但又不能修改现有代码的情况。为了避免继承带来的复杂性和维护难度&#xff0c;桥接模式&#xff08;Bridge Pattern&#xff09;应运而生。桥接模式是一种结构型设计模式&#xff0c;旨在解耦抽象部分和…

轨道交通3U机箱CPCI电机控制板(DSP),主要运行控制算法以对牵引电机进行精准的运动控制

板卡简介&#xff1a; 本板为电机控制板&#xff08;DSP&#xff09;&#xff0c;主要运行控制算法以对牵引电机进行精准的运动控制。 性能规格&#xff1a; 电源&#xff1a;DC5V&#xff0c;DC3.3V DSP&#xff1a;TMS320F28335 x 2 FPGA&#xff1a;XC6SLX25-2FG484I 存…

大模型高效优化技术全景解析:微调、量化、剪枝、梯度裁剪与蒸馏

目录 微调&#xff08;Fine-tuning&#xff09;量化&#xff08;Quantization&#xff09;剪枝&#xff08;Pruning&#xff09;梯度裁剪&#xff08;Gradient Clipping&#xff09;知识蒸馏&#xff08;Knowledge Distillation&#xff09;技术对比与协同策略总结与趋势 1. 微…

SQL Server运维实战:十大高频问题分析与解决方案

友情提示&#xff1a;本文内容由银河易创&#xff08;https://ai.eaigx.com&#xff09;AI创作平台DeepSeek-v3模型生成&#xff0c;文中所梳理的SQL Server运维中十大高频问题及解决方案均由AI生成&#xff0c;仅供参考。 引言 SQL Server作为企业级关系型数据库的核心组件&a…

R语言的链表合并

R语言的链表合并 在计算机科学中&#xff0c;链表是一种常用的数据结构&#xff0c;通过节点&#xff08;node&#xff09;来动态存储数据。与传统的数组不同&#xff0c;链表的每个元素&#xff08;节点&#xff09;都包含指向下一个元素的指针&#xff0c;这种结构使得插入和…

WiFi 定位技术:守护宠物安全的隐形卫士

一、实时追踪&#xff0c;防患未然 想象一下&#xff0c;活泼好动的猫咪趁你开门瞬间溜出家门&#xff0c;穿梭在楼道杂物间&#xff1b;或是狗狗在户外玩耍时&#xff0c;被突发声响惊吓狂奔&#xff0c;瞬间没了踪影。在这些令人揪心的时刻&#xff0c;WiFi 定位技术就像给宠…