LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品
LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品?
提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
文章目录
- LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品?
- @[TOC](文章目录)
- 题目
- 一、审题
- 你认为互联网大厂的题目怎么考你???可不就是改编LeetCode高频题来考吗
- 最长公共子序列的长度
- 本题解题代码:
- 总结
题目
一、情节
双胞胎小弟小王和小李来自小镇,最近一起报名参加了小镇的闯关游戏,官方也为参赛选手准备了翻译机,办公本,录音笔,耳机啥的精美奖品,但是想获得礼物,得经历一番考验,终于大赛到了……
二、游戏规则
俩兄弟分配到不同的闯关主题,分别为游戏A,和游戏B;
A和B游戏均设有关卡,但关卡数不一定相同,主办方预先为每一个关卡设置了一个奖品,如果通过则获得该奖品,否则不行,但是允许选手继续通过下一个关卡;
关卡间是否同通过没有关系
闯关结束后,分别对两兄弟手中的奖品按照其获得的顺序一一匹配,如果两兄弟奖品完全一样,则获得的奖品都可以带回家,否则无法获得。
三、问题
两兄弟加起来最多可以获得多少分份奖品?
输入描述:
为了方便对比,官方将奖品编号
输入为2行字符串
第一行是代表游戏A下每个关卡提供的礼品编号
第二行是代表游戏B下每个关卡提供的礼品编号
礼物的编号范围是字符a–z和数字0–9,游戏关卡数为1–100范围内的整数
输出描述:
两兄弟加起来最多可以获得的奖品数量
一、审题
示例:
输入
123451
1678596
输出
4
你认为互联网大厂的题目怎么考你???可不就是改编LeetCode高频题来考吗
换汤不换药……
换汤不换药……
换汤不换药……
你瞅瞅
说了半天,输入是啥???2个字符串
输出是啥,要求俩字符串对比,里面的相同编号的个数????这是啥???
求最长公共子序列的长度啊
管你字符是a–z还是0–9啊
就是求最长公共子序列长度len,这是一个人得到的奖品
两兄弟能得到最多的奖品数就是2*len
因此,大厂的题目就是给你绕半天,希望你有基础能力学过基础数据结构与算法,直接就能破解本题
最长公共子序列的长度
我说过的
【1】求字符串s1和s2的最长公共子序列的长度
你看看我那个文章就知道,只需要一行代码搞定本题
我再说一遍
2个字符串的动态规划,典型的就是多样本位置对应模型,讨论填表的时候,只看位置i和j的情况
我们定义一个表格dp
维度N*M
N是s1字符串长度
M是s2字符串长度
我们定义dpij是啥?从s1的0–i范围与s2的0–j范围上的最长公共子序列的长度是?
有了这个表,非常简单,咱就是填一个表
最后要啥结果?len = dp[N-1][M-1],即s1整个串,和s2整个串的最长公共子序列长度是??
(0)那么我们填写第dp00格子
就是s1和s20位置相同吗?相同就是1,否则就是0
(1)填第0行,dp0j
只有s1的0字符,和s2的0–j范围内对比
显然,只要s2的0–j有一个字符和s1[0]相等,那就是1,否则就不行
因此,咱们先对比s2[j]是否与s1[0]相等?是就填1【看下面粉色?】
否?那就要看看dp[0][j-1]了,就看看s20–j-1上还有没有可能,反正之前填好的,如果前面有一个能对上,就可以填1
【看上面粉色?左边那些格子的情况了】
这个你懂?
(1)同理,填第0列,dpi0
一样的道理,然你对你看看s1的0–i范围内,有没有一个字符与s2[0]相等
就先看s1[i]是否与s2[0]相等?是,那就dpi0=1【看下面蓝色?的格子】
否则,就只能看看s1的0–i-1范围内,有没有一个字符与s2[0]相等,
即dpi0=dp[i-1][0],如果前面有一个字符能对上就行
okay
第0行,第0列都对上了,剩下的就是常规填表任意位置dpij格子
因为我们最后要右下角的格子
所以宏观调度呢?就从上到下,每一行,都是从左往右填写格子,这个思路我讲了多次了哦!
(2)那么任意位置dpij怎么填呢???
我说过了:我们定义dpij是啥?从s1的0–i范围与s2的0–j范围上的最长公共子序列的长度是?
咱们就围绕这个定义来玩
有这么几种可能性:
【1】就是压根,s1和s2的最长公共子序列,既不以s1的i字符结尾,也不以s2的j字符结尾
这种情况dpij就跟0–i-1和0–j-1没区别对吧?
你想想,都不以ij结尾,那跟不加ij字符,而和前面已经有的字符串,的最长公共子序列有啥区别呢?
比如:
既然d不是e,那有没有d和e没用,直接dpij=dp[i-1][j-1]
懂?
【2】同理,你想到了,s1和s2的最长公共子序列,不以s1的i字符结尾,以s2的j字符结尾
这种情况dpij就跟0–i-1和0–j没区别对吧?
你懂的
不一i结尾,i可以不要,只看s1的0–i-1呗
【3】同理,你想到了,s1和s2的最长公共子序列,以s1的i字符结尾,不以s2的j字符结尾
这种情况dpij就跟0–i和0–j-1没区别对吧?
你懂的
不一j结尾,j可以不要,只看s2的0–j-1呗
【4】同理,你想到了,s1和s2的最长公共子序列,以s1的i字符结尾,以s2的j字符结尾
这种情况就得要求s1[i]=s2[j]
所以就是相当于同时增了1个字符,那就是dpij=dp[0–i-1][0–j-1] + 1
你懂的
以ij结尾
okay,我们的填表规则,基本就OK了
当然你要注意,其实情况【2】【3】实际上在求的时候,直接包含了情况【1】
所以省掉情况【1】
咱们手撕代码:
//最长公共子序列:public static int longestCommonSubSequenceDP(String s1, String s2){int N = s1.length();int M = s2.length();char[] str1 = s1.toCharArray();char[] str2 = s2.toCharArray();//我说过了:我们定义dpij是啥?**从s1的0–i范围与s2的0–j范围上的最长公共子序列的长度是**?int[][] dp = new int[N][M];//(0)那么我们填写第dp00格子//就是s1和s20位置相同吗?相同就是1,否则就是0dp[0][0] = str1[0] == str2[0] ? 1 : 0;//(1)填第0行,dp0j//只有s1的0字符,和s2的0--j范围内对比for (int j = 1; j < M; j++) {dp[0][j] = str1[0] == str2[j] ? 1 : dp[0][j -1];}//(1)同理,填第0列,dpi0//一样的道理,然你对你看看s1的0--i范围内,有没有一个字符与s2[0]相等for (int i = 1; i < N; i++) {dp[i][0] = str1[i] == str2[0] ? 1 : dp[i - 1][0];}//dpij看最长公共子序列是否与s1的i和s2的j字符的情况,情况23覆盖情况1,如果ij字符相同才有情况4for (int i = 1; i < N; i++) {for (int j = 1; j < M; j++) {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);//情况23if (str1[i] == str2[j])dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);//情况4与他们互斥的,只能其中一个}}return dp[N - 1][M - 1];}
这个代码你必须熟悉,因为经常互联网大厂笔试面试都变着方的考你的
本题解题代码:
我们刚刚求的是2个字符串的最长公共子序列的长度len,它是一个人的最长长度
本题要求的是2兄弟最终获得的奖品数量,不就是2*len吗?
手撕代码,直接搞定
public static void main(String[] args) {Scanner in = new Scanner(System.in);String s1 = in.nextLine();String s2 = in.nextLine();int ans = 2 * longestCommonSubSequenceDP(s1, s2);System.out.println(ans);}
测试:
123451
1678596
4
整体AC
总结
提示:重要经验:
1)互联网大厂的笔试面试题,就是变着方考你基础的数据结构与算法,所以基础数据结构与算法你得熟透了
2)涉及到给你的是2个参数,那么就要考虑是不是多样本位置对应模型的动态规划,分清楚ij格子的状况和ij位置的关系就行
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。
LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品相关推荐
- leetcode算法题--最长公共子序列★
原题链接:https://leetcode-cn.com/problems/longest-common-subsequence/ 动态规划 dp[i][j]表示text1[:i]和text2[:j] ...
- 经典算法题——最长公共子序列
** 解析: ** 此题一共有两个要点: 1.求上述两个最长公共子序列的长度 2.求所有可能出现的最长公共子序列个数,答案可能很大,只要将答案对10^8求余即可 第一个都很好想到,难点在于第二个.下面 ...
- Leetcode刷题-最长公共前缀
Leetcode刷题-最长公共前缀 简介 题目 个人答案及结果 学习一下官方的 简介 最近尝试下大家口口相传的神器 leetcode-cn.com,大家自己注册就可以选择题库进行使用了.我都会先自己出 ...
- LeetCode第1143题最长公共子序列
题目来源 给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度. 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符( ...
- 365天挑战LeetCode1000题——Day 014 每日一题 + 最长公共子序列
文章目录 1. [我能赢吗](https://leetcode.cn/problems/can-i-win/) 1.1 记忆化搜索+DFS+位运算 2. [最长公共子序列](https://leetc ...
- leetcode算法题--最长公共子数组
原题链接:https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/ 相似题目:最长公共子序列 只不过这里必须是连续的, ...
- 数据结构与算法专题——第三题 最长公共子序列
一:作用 最长公共子序列的问题常用于解决字符串的相似度,是一个非常实用的算法,作为码农,此算法是我们的必备基本功. 二:概念 举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如 ...
- leetcode算法题-- 最长递增子序列的个数★
原题链接:https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/ 相关题目:最长上升子序列 lengths ...
- 蓝桥杯第五届省赛JAVA真题----最长公共子序列
一个串的子串是指该串的一个连续的局部.如果不要求连续,则可称为它的子序列. 比如对串: "abcdefg" 而言,"ab","abd",&q ...
最新文章
- 微信JSSDK javascript 开发 代码片段,仅供参考
- Struts2开发基本步骤
- 【论文解读】深度强化学习基石论文:函数近似的策略梯度方法
- 微信扫一扫直接打开手机外部浏览器
- java编译速度_[译] Kotlin VS Java:编译速度大比拼
- 迅捷word转换成pdf转换器 4.1 官方版
- can通道采样频率_CAN波特率计算
- K8s(3):资源清单
- 企业微信小程序 windows 使用 vconsole 调试
- 创业维艰--书摘+乱七八糟
- 程序员 键盘 符号 字符 单词
- l130 华大低功耗mcu_HC32L130国产超低功耗华大MCU芯片介绍
- Programming Rust Fast, Safe Systems Development(译) 表达式(第六章 完)
- 浏览器:CSDN的浏览器助手使用推荐
- 深入 Go 中各个高性能 JSON 解析库
- 彻底解决Qt中文乱码
- 若依框架获取和修改当前登录用户信息
- 【python-02】
- 对中间层的一些浅略的思考
- QQ群630300475介绍
热门文章
- 全球中国活塞式航空发动机市场运营模式分析及规划咨询建议报告2022年版
- SVN解决冲突的方法
- 绝地求生服务器维护9月19日,《绝地求生》9月19日上午停机更新维护 修复诸多BUG...
- 【c++基础】判断是否到文件末尾-eof函数
- 2022年驾驶员考试驾驶员技师考试模拟试题卷及答案
- python os.environ.setdefault,OS.ENVIRON()详解
- 2021-12-13 309
- 10分钟搭建树莓派NAS私有云和KODI影音播放系统 (1)---树莓派4B重大提升,脱胎换骨
- 企业呼叫中心中的隐性成本
- 身体湿气重怎么办?游养乐分享2个祛湿小法宝