给定一个字符串S和一个字符X ,其中 , 对于一些 。任务是返回一个距离数组,该距离表示从字符X到字符串每个其他字符的最短距离。
例子:
Input: S = “geeksforgeeks”, X = ‘e’
Output: [1, 0, 0, 1, 2, 3, 3, 2, 1, 0, 0, 1, 2]
for S[0] = ‘g’ nearest ‘e’ is at distance = 1 i.e. S[1] = ‘e’.
similarly, for S[1] = ‘e’, distance = 0.
for S[6] = ‘o’, distance = 3 since we have S[9] = ‘e’, and so on.
Input: S = “helloworld”, X = ‘o’
Output: [4, 3, 2, 1, 0, 1, 0, 1, 2, 3]
方法1:对于S []中索引i处的每个字符,让我们尝试查找到从左到右,从右到左的下一个字符X的距离。答案将是这两个值中的最小值。
- 当从左向右移动时,我们记得我们看到的最后一个字符X的索引。那么答案是i – prev 。
- 从右向左走时,答案是上一个-i 。
- 我们采用这两个答案中的最小值来创建最终的距离数组。
- 最后,打印数组。
下面是上述方法的实现:
C++
// C++ implementation of above approach
#include
using namespace std;
// Function to return required
// array of distances
void shortestDistance(string S, char X)
{
// Find distance from occurrences of X
// appearing before current character.
int prev = INT_MAX;
vector ans;
for (int i = 0; i < S.length(); i++)
{
if (S[i] == X)
prev = i;
if (prev == INT_MAX)
ans.push_back(INT_MAX);
else
ans.push_back(i - prev);
}
// Find distance from occurrences of X
// appearing after current character and
// compare this distance with earlier.
prev = INT_MAX;
for (int i = S.length() - 1; i >= 0; i--)
{
if (S[i] == X)
prev = i;
if (prev != INT_MAX)
ans[i] = min(ans[i], prev - i);
}
for (auto val: ans)
cout << val << ' ';
}
// Driver code
int main()
{
string S = "helloworld";
char X = 'o';
shortestDistance(S, X);
return 0;
}
// This code is contributed by Rituraj Jain
Java
// Java implementation of above approach
import java.util.*;
class GFG
{
// Function to return required
// array of distances
static void shortestDistance(String S, char X)
{
// Find distance from occurrences of X
// appearing before current character.
int prev = Integer.MAX_VALUE;
Vector ans = new Vector<>();
for (int i = 0; i < S.length(); i++)
{
if (S.charAt(i) == X)
prev = i;
if (prev == Integer.MAX_VALUE)
ans.add(Integer.MAX_VALUE);
else
ans.add(i - prev);
}
// Find distance from occurrences of X
// appearing after current character and
// compare this distance with earlier.
prev = Integer.MAX_VALUE;
for (int i = S.length() - 1; i >= 0; i--)
{
if (S.charAt(i) == X)
prev = i;
if (prev != Integer.MAX_VALUE)
ans.set(i, Math.min(ans.get(i), prev - i));
}
for (Integer val: ans)
System.out.print(val+" ");
}
// Driver code
public static void main(String[] args)
{
String S = "geeksforgeeks";
char X = 'g';
shortestDistance(S, X);
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 implementation of above approach
# Function to return required
# array of distances
def shortestDistance(S, X):
# Find distance from occurrences of X
# appearing before current character.
inf = float('inf')
prev = inf
ans = []
for i,j in enumerate(S):
if S[i] == X:
prev = i
if (prev == inf) :
ans.append(inf)
else :
ans.append(i - prev)
# Find distance from occurrences of X
# appearing after current character and
# compare this distance with earlier.
prev = inf
for i in range(len(S) - 1, -1, -1):
if S[i] == X:
prev = i
if (X != inf):
ans[i] = min(ans[i], prev - i)
# return array of distance
return ans
# Driver code
S = "geeksforgeeks"
X = "g"
# Function call to print answer
print(shortestDistance(S, X))
C#
// C# implementation of above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to return required
// array of distances
public static void shortestDistance(String S, char X){
// Find distance from occurrences of X
// appearing before current character.
int prev = int.MaxValue;
List ans = new List();
for (int i=0; i=0; i--)
{
if (S[i] == X)
prev = i;
if (prev != int.MaxValue)
ans[i] = Math.Min(ans[i], prev-i);
}
foreach (var i in ans)
Console.Write(i + " ");
}
// Driver code
public static void Main(String[] args)
{
String S = "geeksforgeeks";
char X = 'g';
shortestDistance(S, X);
}
}
// This code is contributed by
// sanjeev2552
C++
// C++ implementation of above approach
#include
using namespace std;
// Function to return required
// vector of distances
vector shortestToChar(string s, char c)
{
// list to hold position of c in s
vector list;
// list to hold the result
vector res;
// length of string
int len = s.length();
// Iterate over string to create list
for (int i = 0; i < len; i++) {
if (s[i] == c) {
list.push_back(i);
}
}
int p1, p2, v1, v2;
// max value of p2
int l = list.size() - 1;
// Initialize the pointers
p1 = 0;
p2 = l > 0 ? 1 : 0;
// Create result array
for (int i = 0; i < len; i++) {
// Values at current pointers
v1 = list[p1];
v2 = list[p2];
// Current Index is before than p1
if (i <= v1) {
res.push_back(v1 - i);
}
// Current Index is between p1 and p2
else if (i <= v2) {
// Current Index is nearer to p1
if (i - v1 < v2 - i) {
res.push_back(i - v1);
}
// Current Index is nearer to p2
else {
res.push_back(v2 - i);
// Move pointer 1 step ahead
p1 = p2;
p2 = p2 < l ? (p2 + 1) : p2;
}
}
// Current index is after p2
else {
res.push_back(i - v2);
}
}
return res;
}
// Driver code
int main()
{
string s = "geeksforgeeks";
char c = 'e';
vector res = shortestToChar(s, c);
for (auto i : res)
cout << i << " ";
return 0;
}
// This code is contributed by Shivam Sharma
C
// C implementation of above approach
#include
#define MAX_SIZE 100
// Function to return required
// vector of distances
void shortestToChar(char s[], char c, int* res)
{
// list to hold position of c in s
int list[MAX_SIZE];
// length of string
int len = 0;
// To hold size of list
int l = 0;
// Iterate over string to create list
while (s[len] != '\0') {
if (s[len] == c) {
list[l] = len;
l++;
}
len++;
}
int p1, p2, v1, v2;
// max value of p2
l = l - 1;
// Initialize the pointers
p1 = 0;
p2 = l > 0 ? 1 : 0;
// Create result array
for (int i = 0; i < len; i++) {
// Values at current pointers
v1 = list[p1];
v2 = list[p2];
// Current Index is before than p1
if (i <= v1) {
res[i] = (v1 - i);
}
// Current Index is between p1 and p2
else if (i <= v2) {
// Current Index is nearer to p1
if (i - v1 < v2 - i) {
res[i] = (i - v1);
}
// Current Index is nearer to p2
else {
res[i] = (v2 - i);
// Move pointer 1 step ahead
p1 = p2;
p2 = p2 < l ? (p2 + 1) : p2;
}
}
// Current index is after p2
else {
res[i] = (i - v2);
}
}
}
// Driver code
int main()
{
char s[] = "geeksforgeeks";
char c = 'e';
int res[MAX_SIZE];
shortestToChar(s, c, res);
int i = 0;
while (s[i] != '\0')
printf("%d ", res[i++]);
return 0;
}
// This code is contributed by Shivam Sharma
输出
4 3 2 1 0 1 0 1 2 3
方法2:创建一个保存字符出现的列表,然后创建两个指针,指向该列表中两个紧邻的位置,现在遍历字符串以查找与这两个指针的区别,并将最小值插入结果列表。如果指针2更接近当前字符,则将指针向前移动一级。
- 创建一个在字符串中保留所需字符位置的列表,以及一个用于保存结果数组的空列表。
- 如果列表长度为1,则创建两个指向列表p1 = 0和p2 = 0的指针,否则p2 = 1
- 遍历字符串,并将这些指针(v1 = p1-> value&v2 = p2-> value)的值与当前索引(i)进行比较。
- 如果i <= v1,则将v1-i推入结果列表。
- 否则,如果我<= v2
- 如果我更接近v1,则将i-v1推入结果列表
- 否则将v2-i推入结果列表,并在可能的情况下将指针向前移动一级
- 否则将i-v1推入结果列表
- 返回结果列表
下面是上述方法的实现:
C++
// C++ implementation of above approach
#include
using namespace std;
// Function to return required
// vector of distances
vector shortestToChar(string s, char c)
{
// list to hold position of c in s
vector list;
// list to hold the result
vector res;
// length of string
int len = s.length();
// Iterate over string to create list
for (int i = 0; i < len; i++) {
if (s[i] == c) {
list.push_back(i);
}
}
int p1, p2, v1, v2;
// max value of p2
int l = list.size() - 1;
// Initialize the pointers
p1 = 0;
p2 = l > 0 ? 1 : 0;
// Create result array
for (int i = 0; i < len; i++) {
// Values at current pointers
v1 = list[p1];
v2 = list[p2];
// Current Index is before than p1
if (i <= v1) {
res.push_back(v1 - i);
}
// Current Index is between p1 and p2
else if (i <= v2) {
// Current Index is nearer to p1
if (i - v1 < v2 - i) {
res.push_back(i - v1);
}
// Current Index is nearer to p2
else {
res.push_back(v2 - i);
// Move pointer 1 step ahead
p1 = p2;
p2 = p2 < l ? (p2 + 1) : p2;
}
}
// Current index is after p2
else {
res.push_back(i - v2);
}
}
return res;
}
// Driver code
int main()
{
string s = "geeksforgeeks";
char c = 'e';
vector res = shortestToChar(s, c);
for (auto i : res)
cout << i << " ";
return 0;
}
// This code is contributed by Shivam Sharma
C
// C implementation of above approach
#include
#define MAX_SIZE 100
// Function to return required
// vector of distances
void shortestToChar(char s[], char c, int* res)
{
// list to hold position of c in s
int list[MAX_SIZE];
// length of string
int len = 0;
// To hold size of list
int l = 0;
// Iterate over string to create list
while (s[len] != '\0') {
if (s[len] == c) {
list[l] = len;
l++;
}
len++;
}
int p1, p2, v1, v2;
// max value of p2
l = l - 1;
// Initialize the pointers
p1 = 0;
p2 = l > 0 ? 1 : 0;
// Create result array
for (int i = 0; i < len; i++) {
// Values at current pointers
v1 = list[p1];
v2 = list[p2];
// Current Index is before than p1
if (i <= v1) {
res[i] = (v1 - i);
}
// Current Index is between p1 and p2
else if (i <= v2) {
// Current Index is nearer to p1
if (i - v1 < v2 - i) {
res[i] = (i - v1);
}
// Current Index is nearer to p2
else {
res[i] = (v2 - i);
// Move pointer 1 step ahead
p1 = p2;
p2 = p2 < l ? (p2 + 1) : p2;
}
}
// Current index is after p2
else {
res[i] = (i - v2);
}
}
}
// Driver code
int main()
{
char s[] = "geeksforgeeks";
char c = 'e';
int res[MAX_SIZE];
shortestToChar(s, c, res);
int i = 0;
while (s[i] != '\0')
printf("%d ", res[i++]);
return 0;
}
// This code is contributed by Shivam Sharma
输出
1 0 0 1 2 3 3 2 1 0 0 1 2
时间复杂度: O(n)
空间复杂度: O(n)