提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
ONE
题目:
给你一个下标从 0 开始的 环形 字符串数组 words 和一个字符串 target 。环形数组 意味着数组首尾相连。
形式上, words[i] 的下一个元素是 words[(i + 1) % n] ,而 words[i] 的前一个元素是 words[(i - 1 + n) % n] ,其中 n 是 words 的长度。
从 startIndex 开始,你一次可以用 1 步移动到下一个或者前一个单词。
返回到达目标字符串 target 所需的最短距离。如果 words 中不存在字符串 target ,返回 -1 。
示例:
输入:words = ["hello","i","am","leetcode","hello"], target = "hello", startIndex = 1
输出:1
解释:从下标 1 开始,可以经由以下步骤到达 "hello" :
- 向右移动 3 个单位,到达下标 4 。
- 向左移动 2 个单位,到达下标 4 。
- 向右移动 4 个单位,到达下标 0 。
- 向左移动 1 个单位,到达下标 0 。
到达 "hello" 的最短距离是 1 。
解析:
代码:
class Solution {
public int closetTarget(String[] words, String target, int startIndex) {
// 分别向左和向右查找,比较最小值
return Math.min(fwdLeft(words, target, startIndex), fwdRight(words, target, startIndex));
}
// 向左查找
private int fwdLeft(String[] words, String target, int startIndex) {
int step = 0;
int[] indexArr = {startIndex, words.length - 1};
for (int index : indexArr) {
for (int i = index; i >= 0; i--) {
if (words[i].equals(target)) {
return step;
} else {
step++;
}
}
}
// un reachable
return -1;
}
// 向右查找
private int fwdRight(String[] words, String target, int startIndex) {
int step = 0;
int[] indexArr = {startIndex, 0};
for (int index : indexArr) {
for (int i = index; i < words.length; i++) {
if (words[i].equals(target)) {
return step;
} else {
step++;
}
}
}
// un reachable
return -1;
}
}
TWO
题目:
给你一个由字符 'a'、'b'、'c' 组成的字符串 s 和一个非负整数 k 。每分钟,你可以选择取走 s 最左侧
还是 最右侧 的那个字符。
你必须取走每种字符 至少 k 个,返回需要的 最少 分钟数;如果无法取到,则返回 -1 。
示例:
输入:s = "aabaaaacaabc", k = 2
输出:8
解释:
从 s 的左侧取三个字符,现在共取到两个字符 'a' 、一个字符 'b' 。
从 s 的右侧取五个字符,现在共取到四个字符 'a' 、两个字符 'b' 和两个字符 'c' 。
共需要 3 + 5 = 8 分钟。
可以证明需要的最少分钟数是 8 。
解析:
不带前缀的话,从最右侧开始找有 baaaacaabc共十分钟
带前缀的话,从左侧开始找aab+caabc共八分钟
使用滑动窗口找中间最长的片段使a最多移除aCnt-k个, b最多移除bCnt-k个, c最多移除cCnt-k个
代码:
class Solution {
public int takeCharacters(String s, int k) {
char[] chars = s.toCharArray();
int[] cnt = new int[3];
for (char c : chars) {
cnt[c - 'a']++;
}
if (cnt[0] < k || cnt[1] < k || cnt[2] < k) {
return -1;
}
// 使用滑动窗口找中间最长的片段使a最多移除aCnt-k个, b最多移除bCnt-k个, c最多移除cCnt-k个
int[] currentCnt = new int[3];
int maxWindowSize = 0;
int left = 0;
int right = 0;
while (left < chars.length) {
if (right < chars.length) {
currentCnt[chars[right++] - 'a']++;
}
while ((currentCnt[0] > cnt[0] - k || currentCnt[1] > cnt[1] - k || currentCnt[2] > cnt[2] - k) && left < chars.length) {
currentCnt[chars[left++] - 'a']--;
}
maxWindowSize = Math.max(maxWindowSize, right - left);
if (right == chars.length) {
break;
}
}
return s.length() - maxWindowSize;
}
}