📜  给定字符到其他字符的最短距离

📅  最后修改于: 2021-04-27 17:24:33             🧑  作者: Mango

给定一个字符串S和一个字符X ,其中X\varepsilon S[i]      , 对于一些0\leq i \leq S.length()-1      。任务是返回一个距离数组,该距离表示从字符X到字符串每个其他字符的最短距离。
例子:

方法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 = 0p2 = 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)