vlambda博客
学习文章列表

菜鸡决定在LeetCode第87场周赛后暂时停更一段时间

今天有点累,实在是不想打,好不容易的周末想要休息一下。

但是仔细一想,今天要是不刷一题的话,啥事没干啊哈哈,所以还是从床上爬起来整理下稀疏的头发,从挤不出来的牙膏中挤出一点牙膏把牙刷完之后端坐在电脑面前。

论做题的仪式感,一定要坐姿端正。

就开始了一道题做一天的状态。

我们一起来看看力扣第87场周赛。

LeetCode 844. 比较含退格的字符串

题目是这样的:

这道题目就是把#号当成退格键,只要有一个#号字符,那么代表这个#号前面的字符就得去掉。

所以直接采用模拟的方法就能做出来。

我这里是从后面往前遍历,记录下#号字符出现的次数,只要#号字符的次数大于0,那遍历到具体字母字符的时候这个字符就不算有效。

使用两个StringBuilder作为最终字符串结果的容器存储每一个有效的字母。

贴下代码:

class Solution {
public boolean backspaceCompare(String s, String t) {
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
char[] arr1 = s.toCharArray();
char[] arr2 = t.toCharArray();
// 记录退格字符的个数
int cnt = 0;
for(int i = arr1.length - 1; i >= 0; i--){
if(arr1[i] == '#'){
cnt++;
}else if (cnt > 0){
cnt--;
}else{
s1.append(arr1[i]);
}
}
cnt = 0;
for(int i = arr2.length - 1; i >= 0; i--){
if(arr2[i] == '#'){
cnt++;
}else if (cnt > 0){
cnt--;
}else{
s2.append(arr2[i]);
}
}

return s1.toString().equals(s2.toString());
}
}

LeetCode 845. 数组中的最长山脉

题目是这样的:

这道题目看完题目,理解下来就是一个满足的山脉数组长度必须是大于3,题目给定了一个数组,我们需要校验所有的子数组是否是满足条件的山脉数组。

那么我们就从数组的第二个元素开始把每个元素都假设为山脉数组的山顶,然后遍历这个山顶的左右两边是否能够向两边延伸,记录这一次的数组长度。

每次获取到一个满足的山脉数组的长度,就与已有的最大值相比较,如果大于已有的值,则更新。

写下的代码就是这样的:

class Solution {
public int longestMountain(int[] arr) {
int res = 0;
if(arr.length < 3){
return res;
}
// 从第二个位置开始
for(int i = 1; i < arr.length - 1; i++){
// 将当前i的位置视为山顶,如果一开始左边或者右边没有符合条件的值就直接跳过这一次遍历
if((arr[i] - arr[i-1]) <= 0 ||
(arr[i+1] - arr[i]) >= 0){
continue;
}
int temp = i;
int cnt = 0;
// 向左遍历看看有几个符合要求的数
while((i-1) >= 0 && arr[i] - arr[i-1] > 0 ){
cnt++;
i--;
}
i = temp;
// 向右遍历看看有几个符合要求的数
while( i + 1 < arr.length && arr[i + 1] - arr[i] < 0){
cnt++;
i++;
}
res = Math.max(res, cnt + 1);//山顶本身也要算进去
}
return res;
}
}

LeetCode 846. 一手顺子

题目是这样的:

这道题目的意思就是要把hand数组分成几个组,每个组的长度正好是groupSize,而且每个组都必须是从小到大连续的数字。

要实现这样的效果,我们第一步就需要将hand数组进行排序,从排序好的第一个数字开始,必须从之后的数字都必须找到刚好大于1的数字,不然就直接返回false。

所以,我们先使用一个map来统计每个数字出现的次数,每个数字消耗掉一次就必须将次数减一。

想清楚了这个过程就还好。

其实我也是耐耐心心看题解才明白的。

贴下题解代码:

class Solution {
public boolean isNStraightHand(int[] hand, int groupSize) {
int n = hand.length;
if( n % groupSize != 0){
return false;
}

// 数组进行排序预处理,并将元素及其出现次数存储在 map 中
Arrays.sort(hand);
Map<Integer, Integer> map = new HashMap<>();
for (int i : hand) {
map.put(i, map.getOrDefault(i, 0) + 1);
}
for (int h : hand) {
if (map.get(h) > 0) {
// 判断 map 中是否有足够的元素构成顺子
for (int j = 0; j < groupSize; j++) {
if (map.getOrDefault(h + j, 0) > 0) {
map.put(h + j, map.get(h + j) - 1);
} else {
return false;
}
}
}
}
return true;
}
}

第四题看了一下题目是关于图的连通性的问题吧,很抱歉,我不会。


唠唠嗑

算上今天这篇,LeetCode总共是看了10周周赛的题目,很多中等题和困难题都是不会做的,所以实际上算起来并没有做10周周赛的题目。

总的来说简单题如果不是很奇怪的话,一般是没啥问题,主要考验的就是敲代码的手速了,尽管我有一双笨手,实在是只会一指禅敲代码。

中等题的话还是看缘分,因为有些题目是我比较喜欢的类型,我就可能运气好能做出来,我还是比较喜欢做那种深搜、回溯或者模拟的题目,只要确定好函数的入参,一步一步地求解即可。

但是有些中等题真的是超出自己认知,不看题解根本没有思路,刷题还是要多刷,多刷题见的题目多了,没准你就有思路了。

困难题的话还是太难了,我觉得困难题不需要强求,工作中其实也用不到这么高深的算法。

刷题于我更多的目的还是锻炼自己的思维,提高自己bug free的能力。

多么想啥时候我写的crud代码能够非常优雅,bug很少,一遍运行成功呢(想想而已)。

给自己打个气,你很棒,继续加油!

虽然离全年30周周赛的计划还有很远。。。。

但是我决定还是暂时停下脚步,LeetCode周赛文章的更新会暂停一段时间。

刷题实在是一件比较消耗脑力的事情,每天搬砖完之后继续刷题然后写文章(虽然很多内容都是直接拷贝代码)有点吃力,我也深知自己目前的水平还是有较大差距,但是我不会认输的哦。菜鸡想A四题。

所以后面的计划应该暂时会把更新文章的重点放在阅读外文30篇的这个计划上面,说不准我也会更新些其他自己觉得有趣的东西吧。

可能你们不知道,我爱英语。英语也会爱我吧。

希望大家和我一起感受英语的魅力,有什么好的文章记得分享给我。自从高中毕业之后就没怎么好好学过英语了,但特别感谢那时候的英语老师,英语语法至少潜移默化地印在脑海里。。。

加油,爱你们,如果你们看到这里的话,哈哈。

End