当前位置: 首页 > news >正文

wy的leetcode刷题记录_Day70

wy的leetcode刷题记录_Day70

声明

本文章的所有题目信息都来源于leetcode
如有侵权请联系我删掉!
时间:

前言

目录

  • wy的leetcode刷题记录_Day70
    • 声明
    • 前言
    • 466. 统计重复个数
      • 题目介绍
      • 思路
      • 代码
      • 收获
    • 70. 爬楼梯
      • 题目介绍
      • 思路
      • 代码
      • 收获

466. 统计重复个数

今天的每日一题是:466. 统计重复个数

题目介绍

定义 str = [s, n] 表示 str 由 n 个字符串 s 连接构成。

例如,str == [“abc”, 3] ==“abcabcabc” 。
如果可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。

例如,根据定义,s1 = “abc” 可以从 s2 = “abdbec” 获得,仅需要删除加粗且用斜体标识的字符。
现在给你两个字符串 s1 和 s2 和两个整数 n1 和 n2 。由此构造得到两个字符串,其中 str1 = [s1, n1]、str2 = [s2, n2] 。

请你找出一个最大整数 m ,以满足 str = [str2, m] 可以从 str1 获得。

示例 1:
输入:s1 = “acb”, n1 = 4, s2 = “ab”, n2 = 2
输出:2

示例 2:
输入:s1 = “acb”, n1 = 1, s2 = “acb”, n2 = 1
输出:1

思路

好好好,三个月没写代码上来给一个hard题,行,我直接CV,写不了一点。
看了题解后发现其实就是寻找循环结:通俗一点就是在一个循环结中存在n1个s1中对应n2个s2,即寻找n1与n2的关系。而对于最后一个循环结可能是不完整的,所以对于最后一个循环结直接采用暴力匹配即可。
其次,这边不是很懂他这个循环结的寻找方式啊,到时候再看看题解。

代码

class Solution {
public:int getMaxRepetitions(string s1, int n1, string s2, int n2) {if (n1 == 0) {return 0;}int s1cnt = 0, index = 0, s2cnt = 0;// recall 是我们用来找循环节的变量,它是一个哈希映射// 我们如何找循环节?假设我们遍历了 s1cnt 个 s1,此时匹配到了第 s2cnt 个 s2 中的第 index 个字符// 如果我们之前遍历了 s1cnt' 个 s1 时,匹配到的是第 s2cnt' 个 s2 中同样的第 index 个字符,那么就有循环节了// 我们用 (s1cnt', s2cnt', index) 和 (s1cnt, s2cnt, index) 表示两次包含相同 index 的匹配结果// 那么哈希映射中的键就是 index,值就是 (s1cnt', s2cnt') 这个二元组// 循环节就是;//    - 前 s1cnt' 个 s1 包含了 s2cnt' 个 s2//    - 以后的每 (s1cnt - s1cnt') 个 s1 包含了 (s2cnt - s2cnt') 个 s2// 那么还会剩下 (n1 - s1cnt') % (s1cnt - s1cnt') 个 s1, 我们对这些与 s2 进行暴力匹配// 注意 s2 要从第 index 个字符开始匹配unordered_map<int, pair<int, int>> recall;pair<int, int> pre_loop, in_loop;while (true) {// 我们多遍历一个 s1,看看能不能找到循环节++s1cnt;for (char ch: s1) {if (ch == s2[index]) {index += 1;if (index == s2.size()) {++s2cnt;index = 0;}}}// 还没有找到循环节,所有的 s1 就用完了if (s1cnt == n1) {return s2cnt / n2;}// 出现了之前的 index,表示找到了循环节if (recall.count(index)) {auto [s1cnt_prime, s2cnt_prime] = recall[index];// 前 s1cnt' 个 s1 包含了 s2cnt' 个 s2pre_loop = {s1cnt_prime, s2cnt_prime};// 以后的每 (s1cnt - s1cnt') 个 s1 包含了 (s2cnt - s2cnt') 个 s2in_loop = {s1cnt - s1cnt_prime, s2cnt - s2cnt_prime};break;} else {recall[index] = {s1cnt, s2cnt};}}// ans 存储的是 S1 包含的 s2 的数量,考虑的之前的 pre_loop 和 in_loopint ans = pre_loop.second + (n1 - pre_loop.first) / in_loop.first * in_loop.second;// S1 的末尾还剩下一些 s1,我们暴力进行匹配int rest = (n1 - pre_loop.first) % in_loop.first;for (int i = 0; i < rest; ++i) {for (char ch: s1) {if (ch == s2[index]) {++index;if (index == s2.size()) {++ans;index = 0;}}}}// S1 包含 ans 个 s2,那么就包含 ans / n2 个 S2return ans / n2;}
};

收获

没啥收获,太难了,仔细看了下题解能看懂,希望过几天能回来复现一下!

70. 爬楼梯

本题来自动态规划基础篇之——70. 爬楼梯

题目介绍

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶

示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 2 阶 + 1 阶

思路

方法一:一般直接递归,递推函数F(n)=F(n-1)+F(n-2),(n>=2),其中F(1)=1,F(2)=2。F(n)表示第n阶台阶有多少种方式走上去,而根据只能通过走一阶和走两阶这二中方式才行,所以得出递推公式。(递归也可以,递推也行)
方法二:矩阵快速幂
我就不多说了,去看下题解,解的很巧,一般用于其次方程组,非齐次也可以转为为齐次再用这个方法。
方法三:通项公式
计算机的尽头是数学!

代码

递推:

class Solution {
public:int climbStairs(int n) {if(n==1)return 1;if(n==2)return 2;int a1=1;int a2=2;int ans=0;for(int i=3;i<=n;i++){ans=a1+a2;a1=a2;a2=ans;}return ans;}
};

矩阵快速幂:(转载自力扣官方题解)

class Solution {
public:vector<vector<long long>> multiply(vector<vector<long long>> &a, vector<vector<long long>> &b) {vector<vector<long long>> c(2, vector<long long>(2));for (int i = 0; i < 2; i++) {for (int j = 0; j < 2; j++) {c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];}}return c;}vector<vector<long long>> matrixPow(vector<vector<long long>> a, int n) {vector<vector<long long>> ret = {{1, 0}, {0, 1}};while (n > 0) {if ((n & 1) == 1) {ret = multiply(ret, a);}n >>= 1;a = multiply(a, a);}return ret;}int climbStairs(int n) {vector<vector<long long>> ret = {{1, 1}, {1, 0}};vector<vector<long long>> res = matrixPow(ret, n);return res[0][0];}
};

收获

矩阵快速幂这种方式十分的快,在解决某些有规律的递推公式上有着十分迅速的解决方式以及是分小的开销。

相关文章:

  • 配置ssh免密登录
  • Vue学习计划-Vue3--核心语法(一)OptionsAPI、CompositionAPI与setup
  • go 使用 - sync.Metux
  • 计算机网络【Cookie和session机制】
  • 计算机软件考试试题——附答案
  • 使用Vite创建React + TypeScript(node版本为16.17.0,含资源下载)
  • 再见2023,你好2024!
  • Javascript 正则表达式零宽断言
  • 【算法】哈希算法和哈希表
  • git unable to create temporary file: No space left on device(git报错)
  • 文件内容搜索利器 - grep
  • 【谷歌云】注册谷歌云 创建Compute Engine
  • Spring-IOC-xml方式
  • MySQL中的索引之分类,原理,作用,优缺点和执行计划
  • nginx+keepalived实现七层负载
  • @jsonView过滤属性
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • React Native移动开发实战-3-实现页面间的数据传递
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • XML已死 ?
  • 从setTimeout-setInterval看JS线程
  • 仿天猫超市收藏抛物线动画工具库
  • 理解在java “”i=i++;”所发生的事情
  • 试着探索高并发下的系统架构面貌
  • 学习笔记:对象,原型和继承(1)
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ###STL(标准模板库)
  • (1)常见O(n^2)排序算法解析
  • (libusb) usb口自动刷新
  • (二)fiber的基本认识
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (翻译)terry crowley: 写给程序员
  • (附源码)php投票系统 毕业设计 121500
  • (一)基于IDEA的JAVA基础12
  • (转)Android学习笔记 --- android任务栈和启动模式
  • ..回顾17,展望18
  • ./configure、make、make install 命令
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .gitattributes 文件
  • .Mobi域名介绍
  • .NET Core中的去虚
  • /var/log/cvslog 太大
  • [2017][note]基于空间交叉相位调制的两个连续波在few layer铋Bi中的全光switch——
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [ACM] hdu 1201 18岁生日
  • [BUUCTF 2018]Online Tool
  • [BZOJ] 2044: 三维导弹拦截
  • [C#] 如何调用Python脚本程序
  • [C++]AVL树怎么转
  • [codeforces]Levko and Permutation
  • [Go WebSocket] 多房间的聊天室(三)自动清理无人房间
  • [hive]中的字段的数据类型有哪些
  • [Interview]Java 面试宝典系列之 Java 多线程
  • [LeetCode]-Integer to Roman 阿拉伯数字转罗马数字