携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
第85场双周赛-力扣
第85场双周赛-力扣
啊真是服了,1,2题合起来十分钟就ac了,第三题一直超时,也意识到问题了,最后想到了解决方法,做完提交的时候已经12点01了,差点三题选手。
2381. 字母移位 II
给你一个小写英文字母组成的字符串 s 和一个二维整数数组 shifts ,其中 shifts[i] = [starti, endi, directioni] 。对于每个 i ,将 s 中从下标 starti 到下标 endi (两者都包含)所有字符都进行移位运算,如果 directioni = 1 将字符向后移位,如果 directioni = 0 将字符向前移位。
将一个字符 向后 移位的意思是将这个字符用字母表中 下一个 字母替换(字母表视为环绕的,所以 'z' 变成 'a')。类似的,将一个字符 向前 移位的意思是将这个字符用字母表中 前一个 字母替换(字母表是环绕的,所以 'a' 变成 'z' )。
请你返回对 s 进行所有移位操作以后得到的最终字符串。
示例 1
- 输入:s = "abc", shifts = [[0,1,0],[1,2,1],[0,2,1]]
- 输出:"ace"
- 解释:首先,将下标从 0 到 1 的字母向前移位,得到 s = "zac" 。
- 然后,将下标从 1 到 2 的字母向后移位,得到 s = "zbd" 。
- 最后,将下标从 0 到 2 的字符向后移位,得到 s = "ace" 。
示例 2
- 输入:s = "dztz", shifts = [[0,0,0],[1,1,1]]
- 输出:"catz"
- 解释:首先,将下标从 0 到 0 的字母向前移位,得到 s = "cztz" 。
- 最后,将下标从 1 到 1 的字符向后移位,得到 s = "catz" 。
提示:
- 1 <= s.length, shifts.length <= 5 * 104
- shifts[i].length == 3
- 0 <= starti <= endi < s.length
- 0 <= directioni <= 1
- s 只包含小写英文字母。
2.解法一
这个题的思路并不难,首先按照其要求的循环遍历就可以实现这个功能。但是作为第三题哪还没有点坑呢,肯定有用例会超时的。
直接按照题目要求,进行循环位移。最后超时,通过37/39的用例。
class Solution {
public String shiftingLetters(String s, int[][] shifts) {
char[] chars = s.toCharArray();
for(int i = 0; i < shifts.length; i++) {
fun(chars, shifts[i]);
// System.out.printlnn(Arrays.tostring(chars));
}
return new String(chars);
}
public void fun(char[] chars, int[] shift) {
int start = shift[0];
int end = shift[1];
int type = shift[2];
if(shift[2] == 0) {
for(int i = start; i <= end; i++) {
chars[i] = qian(chars[i]);
}
} else {
for(int i = start; i <= end; i++) {
chars[i] = hou(chars[i]);
}
}
}
public char qian(char c) {
if(c == 'a') {
return 'z';
} else {
return (char)(c - 1);
}
}
public char hou(char c) {
if(c == 'z') {
return 'a';
} else {
return (char)(c + 1);
}
}
}
2.解法二
这里我在两个地方进行了优化
优化一,在fun函数中,如果改变的次数为n,并不会直接去改变n次,而是先将n%26后,进行位移。
优化二(第一种),用了一个move数组,记录每个位置的字符要改变的值(正数代表后移,负数代表前移)也是会超时,其实这个方法和解法一并没有太多的区别,解法一是直接改变字符,优化后是先累计,后一起改变。
优化二(最终版)还是用了move数组记录了位于i前面的字符需要位移的值,而后,用sum数组记录位于i的字符需要位移的值。再进行位移,这样时间复杂度就降低多了。
class Solution {
public String shiftingLetters(String s, int[][] shifts) {
char[] chars = s.toCharArray();
int[] move = new int[chars.length];
for(int i = 0; i < shifts.length; i++) {
if(shifts[i][2]==0) {
int start = shifts[i][0];
if(start > 0) {
move[start - 1]++;
}
move[shifts[i][1]]--;
} else {
int start = shifts[i][0];
if(start>0) {
move[start - 1]--;
}
move[shifts[i][1]]++;
}
}
int sum = 0;
for(int i = 0; i < move.length; i++) {
sum = sum + move[i];
}
int[] move2 = new int[chars.length];
for(int i = 0; i < move2.length; i++) {
move2[i] += sum;
sum = sum - move[i];
}
for(int i = 0; i < chars.length; i++) {
chars[i] = fun(chars[i], move2[i]);
}
return new String(chars);
}
public char fun(char element, int move) {
if(move == 0) return element;
if(move > 0) {
move = move % 26;
char temp = (char)(element + move);
while(temp > 'z') {
temp = (char)(temp - 26);
}
return temp;
} else {
move = (0 - move) % 26;
char temp = (char)(element - move);
while(temp < 'a') {
temp = (char)(temp + 26);
}
return temp;
}
}
}
解析
令我十分伤心的是,提交的时候已经00点00了,没算上分,真是哭死
第一题链接如下
[杨小白]_leetcode_第85场双周赛-第一题2379. 得到 K 个黑块的最少涂色次数
第二题链接如下
[杨小白]_leetcode_第85场双周赛-第二题2380. 二进制字符串重新安排顺序需要的时间
3.结束
差点三题选手,真是哭了,下次一定下次一定,gogogo,刷题刷题,每天一道,三年1000道!!!!