恭喜发现宝藏!搜索公众号【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 实时题库 闪电速递