【备战秋招】每日一题:4月15日美团春招:题面+题目思路 + C++/python/js/Go/java带注释

2023大厂笔试模拟练习网站(含题解)
www.codefun2000.com
最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据,挂载到我们的OJ上,供大家学习交流,体会笔试难度。现已录入200+道互联网大厂模拟练习题,还在极速更新中。欢迎关注公众号“塔子哥学算法”获取最新消息。

提交链接:

https://codefun2000.com/p/P1138

为了更好的阅读体检,可以查看OJ上的题解。进入提交链接,点击右边菜单栏的"查看塔子哥的题解"

在线评测链接:P1235

题目内容

塔子哥是一名优秀的软件工程师,他的公司最近接到了一个新项目,需要在短时间内实现一个新的字符串匹配功能。

在这个项目中,有两个字符串 ST,需要将字符串 S 变换成字符串 T 的一个前缀。这个任务非常重要,因为它将决定整个项目的成功与否。

为了完成这个任务,塔子哥开始进行了大量的研究和分析。他发现,每次操作可以修改 S 的一个字符,也可以删除一个 S 末尾的字符,这样才能将 S 变换成 T 的前缀。

现在塔子哥需要写一段程序,来输出最少需要操作的次数。

输入描述

第一行一个正整数 t ,表示数据组数;

对于每一组数据输入两行仅包含小写字母的字符串 ST

1\le S.length(),T.length()\le 5\times 10^41\le t \le10

输出描述

对于每一组数据,输出一个整数,表示最少需要操作的次数。

样例

输入

2
aba
abb
abcd
efg

输出

1
4

样例解释

第一组数据,可以修改最后一个字母,使得 S=abb ,是 T 的一个前缀;

第二组数据,需要将 S 整个串删除,操作次数为 4 。

思路

思维 + 贪心

当 len(s) > len(t) ,s 中第 len(t) + 1 到 len(s) 这些字符都必须删除。

接下来我们考虑 [1, min(len(s, len(t)))] 的部分。 因为删除只能删除最后一个,所以删除一个字符前,必须删除其后面的所有字符,但是其后面的字符中,可能存在字符和 t 中对应位置的字符相等。

所以最好的操作就是遇到不同的字符则修改。

时间复杂度:O(n)

类似题目推荐

这里推荐几道贪心题目

Leetcode

LeetCode上的贪心题,代码随想录总结的非常好了,见 贪心 - 代码随想录

Codefun2000

  1. P1091. 米哈游 2023.03.19-第一题-交换字符

  2. P1235. 百度 2023.04.15-实习-第一题-字符串前缀

  3. P1005. 腾讯 2022.10.16-汽车

  4. P1137 美团 2023.04.01-第一题-整理

  5. P1077 美团 2023.3.11-第一题-字符串修改

  6. P1024 百度 2022.9.13-01反转

  7. P1089 美团 2023.3.18.10点-第三题-塔子哥的回文串

代码

CPP

#include <bits/stdc++.h>
using namespace std;
​
const int N = 50010;
char s[N], t[N];
int ns, nt;
int n;
​
void solve() {
    scanf("%s%s", s + 1, t + 1);
    ns = strlen(s + 1), nt = strlen(t + 1);
​
    int ans = 0;
    // 如果 s 的长度大于 t 的长度,那么从 s[nt + 1] 到 s[ns] 必然都要删除
    if (ns > nt) ans += ns - nt, ns = nt;
​
    // 如果 s[i] != t[i] ,既然删除(只能修改末字符)和修改的代价相同,不如全部修改
    for (int i = 1; i <= ns; ++i)
        if (s[i] != t[i]) ans += 1;
    printf("%d\n", ans);
}
​
int main()
{
    int T;
    scanf("%d", &T);
    for (int i = 1; i <= T; ++i) {
        solve();
    }
    return 0;
}

python

T = int(input())
while T > 0:
    s = input()
    t = input()
​
    ns = len(s)
    nt = len(t)
​
    ans = 0
    # 如果 s 的长度大于 t 的长度,那么从 s[nt + 1] 到 s[ns] 必然都要删除
    if ns > nt:
        ans += ns - nt
        ns = nt
​
    for i in range(ns):
        # 如果 s[i] != t[i] ,既然删除(只能修改末字符)和修改的代价相同,不如全部修改
        if s[i] != t[i]:
            ans += 1
​
    print(ans)
​
    T -= 1

Java

import java.util.Scanner;
​
public class Main {
​
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
​
        int T = sc.nextInt();
        while (T-- > 0) {
            String s = sc.next();
            String t = sc.next();
​
            int ans = 0;
            // 如果 s 的长度大于 t 的长度,那么从 s[nt + 1] 到 s[ns] 必然都要删除
            int ns = s.length(), nt = t.length();
            if (ns > nt) {
                ans += ns - nt;
                ns = nt;
            }
​
            for (int i = 0; i < ns; ++i) {
                // 如果 s[i] != t[i] ,既然删除(只能修改末字符)和修改的代价相同,不如全部修改
                if (s.charAt(i) != t.charAt(i)) {
                    ans += 1;
                }
            }
​
            System.out.println(ans);
        }
    }
​
}

Go

package main
​
import (
    "fmt"
)
​
const N = 50010
​
func solve(s, t string) {
    ns, nt := len(s), len(t)
​
    ans := 0
    // 如果 s 的长度大于 t 的长度,那么从 s[nt + 1] 到 s[ns] 必然都要删除
    if ns > nt {
        ans += ns - nt
        ns = nt
    }
​
    // 如果 s[i] != t[i] ,既然删除(只能修改末字符)和修改的代价相同,不如全部修改
    for i := 0; i < ns; i++ {
        if s[i] != t[i] {
            ans += 1
        }
    }
    fmt.Printf("%d\n", ans)
}
​
func main() {
    var T int
    fmt.Scan(&T)
    for i := 0; i < T; i++ {
        var s, t string
        fmt.Scan(&s, &t)
        solve(s, t)
    }
}

Js

process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
    input += data;
    return;
});
process.stdin.on('end', () => {
    const lines = input.trim().split('\n');
    const N = 50010;
​
    function solve(s, t) {
        let ns = s.length;
        let nt = t.length;
        let ans = 0;
​
        // 如果 s 的长度大于 t 的长度,那么从 s[nt + 1] 到 s[ns] 必然都要删除
        if (ns > nt) {
            ans += ns - nt;
            ns = nt;
        }
​
        // 如果 s[i] != t[i] ,既然删除(只能修改末字符)和修改的代价相同,不如全部修改
        for (let i = 0; i < ns; i++) {
            if (s[i] !== t[i]) {
                ans += 1;
            }
        }
​
        console.log(ans);
    }
​
    const T = Number(lines[0]);
    for (let i = 0; i < T; i++) {
        s = lines[i * 2 + 1].trim()
        t = lines[i * 2 + 2].trim()
        solve(s, t);
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值