[toc]

估计要掉很多分,麻了,自抱自泣中。只做出了 T1、T2,T3 功败垂成,叹气……
排名 1344 / 2591。
3 分- 交替数字和
4 分- 根据第 K 场考试的分数排序
不知道大佬们都是怎么样在几十秒内秒杀的,实名羡慕。我反正是做的很慢,光第一题就用了10分钟。
难道大佬们都不读题吗?虽然说这两题很简单吧,但我感觉我光理解题意,每道也要耗费至少3分钟,然后尝试执行检查错误,又要花至少 3 分钟。人和人的差距好大😭。
我觉得这一点上我无论怎么练习,也很难提高了,这个受限于我大脑神经网络的效率,天生慢,真的忧伤…… 求安慰,求支招😭
5 分- 执行逐位运算使字符串相等
这道题本来很有希望,真的就差一点点就成功了,值得好好反思一下。
一开始我尝试分类讨论:让 s 和 target 第 i 位的数字组成二进制 01、10、11、00,考察怎样才能把 01 变成 11,把 10 变成 00。
但是自己和自己讨论,讨论着、讨论着就把自己搞晕了,以至于反复检查自己是不是算错了:

上图中的注释就是头脑风暴的过程,这个注释被反复检查修改了 N 遍,到了第 N 遍时,我已经感觉天玄地黄,宇宙洪荒了,彻底把自己绕晕了。
然后尝试着强迫迫自己冷静下来,确定思路:
事后看,这个思路是没问题,但是我编码时,内心很慌张,而且不断怀疑自己。当时只剩 15 分钟了,比赛结束后,我调试了好几次才搞定:
class Solution {
public boolean makeStringsEqual(String s, String target) {
int n = s.length();
int[] cnt = new int[4];
for(int i = 0; i < n; i++){
int k = helper(s.charAt(i), target.charAt(i));
cnt[k]++;
}
while(cnt[1] > 0 && cnt[2] + cnt[3] > 0){
int count = Math.min(cnt[1], cnt[2] + cnt[3]);
cnt[1] -= count;
cnt[3] += count;
}
if(cnt[1] > 0)return false;
if(cnt[2] > 0){
// cnt[2] = 1;
if(cnt[3] < 1)return false;
}
return true;
}
private int helper (char c1, char c2){
return (c1 - '0') * 2 + (c2 - '0');
}
}前面的代码虽然调试通了,但是 while 循环里做了无用的工作。仔细想想就会意识到:只要有一个 10 或者 11,就能像核聚变一样,将所有 01 都转换成 11,所以:
class Solution {
public boolean makeStringsEqual(String s, String target) {
int n = s.length();
int[] cnt = new int[4];
for(int i = 0; i < n; i++){
int k = helper(s.charAt(i), target.charAt(i));
cnt[k]++;
}
if(cnt[1] > 0){ // 只要有 1 个 10 或者 11,就能转换所有 01 为 11。否则,01 无法被消除
if(cnt[2] == 0 && cnt[3] == 0) return false;
cnt[3] += cnt[1];
}
// 10 总是能和自己作用并将其中一个变为 00,所以可以当成只有一个 10;只要有一个 11,就能把这个唯一的 10 也消除。
if(cnt[2] > 0 && cnt[3] == 0) return false;
return true;
}
private int helper (char c1, char c2){
return (c1 - '0') * 2 + (c2 - '0');
}
}去掉 while 循环后,复杂度直接变成了 。
编码跟不上思路,反复 debugger 的戏码历史又重演了。也许是最近太累了,也许是真的笨,总之非常低级的错误,要反复检查好几遍。被自己蠢哭真的是 emo 了。

/*
这一版简直就是在乱写了,已经是慌不择路,徒劳挣扎、胡乱提交了
更离谱的是,我在赛场上把这段代码反复提交了两次,挣扎是没用的
*/
class Solution {
public boolean makeStringsEqual(String s, String target) {
int n = s.length();
int[] cnt = new int[4];
for(int i = 0; i < n; i++){
int k = helper(s.charAt(i), target.charAt(i));
cnt[k]++;
}
if(cnt[1] > 0){
if(cnt[2] + cnt[3] < cnt[1])return false;
cnt[0] = 0; // 事后重看,跟新了 cnt[0],但是后面没有再用到,不知道当时咋想的
}
if(cnt[2] > 0){
cnt[2] = 1; // 事后重看,跟新了 cnt[0],但是后面没有再用到,不知道当时咋想的
if(cnt[3] < 2)return false;
}
return true;
}
private int helper (char c1, char c2){
return (int)(c1 - '0') * 2 + (int)(c2 - '0');
}
}
6 分- 拆分数组的最小代价
据说这道题不难,但我没力气看了。我最近有点刷题刷的走火入魔,或许我需要休息休息了。
祝大家新年快乐~
