【2022-08-27】京东秋招笔试三道编程题

恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经,目前已更新至美团、微软…
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

第一题:小红的矩阵构造

题目描述

题目大概意思是将小红的字符串前K个转为大写,剩余部分转为小写。

代码

Python版本
n, k = list(map(int, input().split(' ')))
s = input()
print(s[:k].upper() + s[k:].lower())
# vx公众号关注TechGuide 实时题库 闪电速递

第二题:嘤嘤的长城

题目描述

给你一个下标从 0 开始的数组 nums ,该数组由 n 个正整数组成。

如果满足下述条件,则数组 nums 是一个 交替数组 :

nums[i - 2] == nums[i] ,其中 2 <= i <= n - 1 。
nums[i - 1] != nums[i] ,其中 1 <= i <= n - 1 。
在一步 操作 中,你可以选择下标 i 并将 nums[i] 更改 为 任一 正整数。

返回使数组变成交替数组的 最少操作数 。

输入输出描述

输入:nums = [3,1,3,2,4,3]
输出:3
解释:
使数组变成交替数组的方法之一是将该数组转换为 [3,1,3,1,3,1] 。
在这种情况下,操作数为 3 。
可以证明,操作数少于 3 的情况下,无法使数组变成交替数组。

思路

力扣2170. 使数组变成交替数组的最少操作数

代码

CPP版本
class Solution {
public:
    int minimumOperations(vector<int>& nums) {
        int n = nums.size();

        // start = 0 表示偶数下标,start = 1 表示奇数下标
        // 返回值为最大键,最大键对应的值,次大键,次大键对应的值
        auto get = [&](int start) -> tuple<int, int, int, int> {
            unordered_map<int, int> freq;
            for (int i = start; i < n; i += 2) {
                ++freq[nums[i]];
            }

            int fstkey = 0, fstval = 0, sndkey = 0, sndval = 0;
            for (const auto& [key, val]: freq) {
                if (val > fstval) {
                    tie(sndkey, sndval) = tuple{fstkey, fstval};
                    tie(fstkey, fstval) = tuple{key, val};
                }
                else if (val > sndval) {
                    tie(sndkey, sndval) = tuple{key, val};
                }
            }

            return {fstkey, fstval, sndkey, sndval};
        };

        auto [e1stkey, e1stval, e2ndkey, e2ndval] = get(0);
        auto [o1stkey, o1stval, o2ndkey, o2ndval] = get(1);

        if (e1stkey != o1stkey) {
            return n - (e1stval + o1stval);
        }
        
        return n - max(e1stval + o2ndval, o1stval + e2ndval);
    }
};
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
n = int(input())
nums = list(map(int, input().split(' ')))
l_dict = collections.Counter(nums[0::2])
r_dict = collections.Counter(nums[1::2])
l = l_dict.most_common(2)
r = r_dict.most_common(2)
if len(l) < 2:
  l.append((0, 0))
if len(r) < 2:
  r.append((0, 0))
cnt = 0
if l[0][0] != r[0][0]:
  cnt = l[0][1] + r[0][1]
else:
  cnt = max(l[0][1] + r[1][1], l[1][1] + r[0][1])
print(n - cnt)
# vx公众号关注TechGuide 实时题库 闪电速递

第三题:小红的漂亮串

题目描述

一个只含小写字母的字符串如果含两个’red’即为漂亮串,如’redared’为漂亮串,‘reedred’不是漂亮串
输入n,输出以长度为n的字符串有多少种可能的漂亮串

思路

抛砖引玉一个朴素易懂的DP:
总的思路是做减法,用 所有长度为n的字符串数 减去 长度为n不含’red’的字符串数 和 长度为n有且仅有一个’red’的字符串数。
维护一个 dp[2][N] 的二维数组, 第一个下标代表字符串中 ‘red’出现的次数,第二个下标代表字符串长度
于是dp[0][i] 即为 长度为 i 其中包含 0 个’red’的字符串个数(即不出现’red’)
于是dp[1][i] 即为 长度为 i 其中包含 1 个’red’的字符串个数
最终结果就应该是很简单的 26^(N) - dp[0][N] - dp[1][N]

重头戏是状态转移防程:
首先考虑 dp[0][i], 分 第 i 位不是’d’ 和 第 i 位是’d’ 两种情况考虑
如果第 i 位不是’d’, 那前面 [0~i-1] 位只要不包含’red’就行,而第i位除’d’以外还有25种选择,dp[0][i-1] * 25
如果第 i 位是’d’,那其前面两位不能是’re’, 考虑从 dp[0][i-1] 中剔除所有的 dp[0][i-3]'re’的情况,第i位只有’d’一种选择,(dp[0][i-1] - dp[0][i-3]) * 1
因此综合来看,dp[0][i] = dp[0][i-1] * 25 + (dp[0][i-1] - dp[0][i-3]) * 1 = dp[0][i-1] * 26 - dp[0][i-3]

其次考虑 dp[1][i], 也分 第 i 位不是’d’ 和 第 i 位是’d’ 两种情况考虑
如果第 i 位不是’d’, 那前面 [0~i-1] 位需要包含一次’red’,而第i位除’d’以外还有25种选择,dp[1][i-1] * 25
如果第 i 位是’d’,那又有两种情况, “ 不包含’red’ 的[0~i-3]+‘red’ ” 或者 “ 包含’red’的[0~i-3]+非’re’+‘d’ ”
“ 不包含’red’的[0~i-3]+‘red’ ”,非常简单,即 dp[0][i-3] * 1
“ 包含’red’的[0~i-3]+非’re’+‘d’ ”的情况与之前类似,考虑从 dp[1][i-1] 中剔除所有的 dp[1][i-3]'re’的情况,第i位只有’d’一种选择,(dp[1][i-1] - dp[1][i-3]) * 1
因此综合来看,dp[1][i] = dp[1][i-1] * 25 + dp[0][i-3] + (dp[1][i-1] - dp[1][i-3]) * 1

代码

CPP版本
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
ll dp[N][4];
void init(int n){
	dp[0][0] = 1;
	for(int i = 1; i <= n; i ++){
		dp[i][0] = (dp[i - 1][0] * 25 % mod + dp[i - 1][1] * 24 % mod + dp[i - 1][2] * 24 % mod) % mod;
		dp[i][1] = (dp[i - 1][0] + dp[i - 1][1] + dp[i - 1][2]) % mod;
		dp[i][2] = dp[i - 1][1];
	}
}
int main()
{
	int n;
	cin >> n;
	ll ans = 1;
	for(int i = 1; i <= n; i ++){
		ans = ans * 26 % mod;
	}
	init(n);
	ans = (ans - (dp[n][0] + dp[n][1] + dp[n][2]) % mod + mod) % mod;
	for(int i = 1; i <= n - 2; i ++){
		ll left = (dp[i - 1][0] + dp[i - 1][1] + dp[i - 1][2]) % mod;
		ll right = (dp[n - i - 2][0] + dp[n - i - 2][1] + dp[n - i - 2][2]) % mod;
		ans = (ans - left * right % mod + mod) % mod;
	}
	cout << ans << endl;
	return 0;
}
// vx公众号关注TechGuide 实时题库 闪电速递
Python版本
#include <iostream>
#include <vector>
using namespace std;
#define MOD 1000000007

long long beautiString(int n){
    long long res = 0;
    vector<vector<long long>> dp(2, vector<long long>(n+1, 0));
    dp[0][0] = 1; dp[0][1] = 26; dp[0][2] = 26 * 26; 
    dp[1][0] = 0; dp[1][1] = 0 ; dp[1][2] = 0;
    res = 26 * 26;
    for(int i = 3; i <= n; i++){
        // 0次red: (dp[0][i-1] * 25) + (dp[0][i-1] - dp[0][i-3])
        //            第i位不是d         第i位是d,前两位不能是re
        //                           需要从 dp[0][i-1] 把 dp[0][i-3]'re' 的情况减去
        dp[0][i] = (dp[0][i-1] * 26 % MOD - dp[0][i-3]) % MOD;
        // 1次red: (dp[1][i-1] * 25) + (dp[0][i-3] + (dp[1][i-1] - dp[1][i-3]))
        //            第i位不是d      第i位是d,两种情况: dp[0][i-3]'red'&nbs***bsp;dp[0][i-3]'re'
        //                            需要从 dp[1][i-1] 把 dp[1][i-3]'re' 的情况减去
        dp[1][i] = (dp[1][i-1] * 25 % MOD + dp[0][i-3] + dp[1][i-1] - dp[1][i-3]) % MOD;
        res      = (res * 26) % MOD;
    }
    res += MOD - (dp[0][n] + dp[1][n]) % MOD;
    return res % MOD;
}

int main(){
    int n = 100;
    cout << beautiString(n);
    return 0;
}
# vx公众号关注TechGuide 实时题库 闪电速递
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2023年3月11日,美团春季招聘笔试中共包含五道编程题目。以下是对每道题目的简要说明: 1. 题目一:这道题目要求解决一个数字统计的问题。可能涉及到的知识点包括数据结构、循环和条件判断等。解决问题的思路可能是使用字典等数据结构来保存统计结果,并使用循环逐个读取输入数据并进行统计。 2. 题目二:这道题目可能是一个字符处理的问题。需要使用字符的方法进行操作,如提取、拼接、查找和替换等。可能的解决思路包括使用正则表达式、切片和遍历等。 3. 题目三:这道题目可能涉及到算法数据结构的知识。可能是一道涉及到数组、链表、树等数据结构的问题。解决思路可能包括遍历、递归、搜索和排序等。 4. 题目四:这道题目可能是一个动态规划的问题。需要根据给定的条件和规则,通过动态规划的方式求解问题。解决思路包括定义状态和转移方程,使用递推或记忆化搜索进行求解。 5. 题目五:这道题目可能是一个图论或网络问题。需要根据给定的图或网络结构,解决一个相关的问题。可能涉及到广度优先搜索、深度优先搜索、最短路径等知识。解决思路可能包括使用图或网络的相关算法进行求解。 以上只是对这五道编程题目的一些可能情况进行的简要描述,具体的题目内容可能会有所不同。希望这些信息能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值