到目标字符串的最短距离
难度:
标签:
题目描述
You are given a 0-indexed circular string array words
and a string target
. A circular array means that the array's end connects to the array's beginning.
- Formally, the next element of
words[i]
iswords[(i + 1) % n]
and the previous element ofwords[i]
iswords[(i - 1 + n) % n]
, wheren
is the length ofwords
.
Starting from startIndex
, you can move to either the next word or the previous word with 1
step at a time.
Return the shortest distance needed to reach the string target
. If the string target
does not exist in words
, return -1
.
Example 1:
Input: words = ["hello","i","am","leetcode","hello"], target = "hello", startIndex = 1 Output: 1 Explanation: We start from index 1 and can reach "hello" by - moving 3 units to the right to reach index 4. - moving 2 units to the left to reach index 4. - moving 4 units to the right to reach index 0. - moving 1 unit to the left to reach index 0. The shortest distance to reach "hello" is 1.
Example 2:
Input: words = ["a","b","leetcode"], target = "leetcode", startIndex = 0 Output: 1 Explanation: We start from index 0 and can reach "leetcode" by - moving 2 units to the right to reach index 3. - moving 1 unit to the left to reach index 3. The shortest distance to reach "leetcode" is 1.
Example 3:
Input: words = ["i","eat","leetcode"], target = "ate", startIndex = 0
Output: -1
Explanation: Since "ate" does not exist in words
, we return -1.
Constraints:
1 <= words.length <= 100
1 <= words[i].length <= 100
words[i]
andtarget
consist of only lowercase English letters.0 <= startIndex < words.length
代码结果
运行时间: 19 ms, 内存: 16.2 MB
/*
* 思路:
* 使用Java Stream来简化代码。
* 我们可以使用IntStream来遍历索引,并计算顺时针和逆时针的距离。
* 使用filter找到目标字符串的位置,然后使用mapToInt计算距离。
* 最后使用min找到最小距离。
*/
import java.util.stream.IntStream;
public class Solution {
public int closetTarget(String[] words, String target, int startIndex) {
int n = words.length;
return IntStream.range(0, n)
.filter(i -> words[i].equals(target))
.map(i -> {
int distanceClockwise = (i - startIndex + n) % n;
int distanceCounterClockwise = (startIndex - i + n) % n;
return Math.min(distanceClockwise, distanceCounterClockwise);
})
.min()
.orElse(-1);
}
}
解释
方法:
题解首先初始化两个计数器x和y分别表示向右和向左查找目标字符串target的距离。从startIndex开始,首先向右循环遍历words数组,每次移动后增加x的计数。如果索引s超过数组长度,则将其重置为0,模拟环形数组的行为。如果向右的遍历次数x超过数组长度而还未找到目标,则返回-1,表示target不在数组中。完成向右的遍历后,同样的方法向左遍历,每次递减索引s,并增加计数器y。向左遍历时如果索引s变为负数,则重置为数组的最后一个元素,再次模拟环形数组。最后,函数返回x和y中的较小值,即为到达target的最短距离。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
题解中提到如果向右遍历的次数超过数组长度还未找到`target`就返回-1,但是这是否考虑了环形数组的特性,即可能需要多轮遍历才能找到目标?
▷🦆
题解中向左搜索时,将索引s调整为数组末尾而不是采用模运算,这种方式是否有特殊的考虑?为什么不使用`(s - 1 + n) % n`的方式来处理?
▷🦆
在题解中使用了两个独立的while循环来分别计算向右和向左的距离,这种实现方式是否会导致重复计算?能否通过一次遍历完成两个方向的搜索?
▷