📜  在字符串中从一个索引遍历到另一索引的最低成本

📅  最后修改于: 2021-04-29 03:10:26             🧑  作者: Mango

给定长度为N的小写字符组成的字符串S ,任务是找到从索引i到索引j达到的最小开销。
在任何索引k处,跳到索引k + 1k-1 (不超出范围)的成本为1。
此外,跳转到任何索引m使得S [m] = S [k]的成本为0。

例子:

方法:

  1. 解决此问题的一种方法是0-1 BFS。
  2. 该设置可以可视化为具有N个节点的图形。
  3. 所有节点将连接到权重为’1’的相邻节点,并且具有相同字符的权重为’0’的节点。
  4. 在此设置中,可以运行0-1 BFS以查找从索引’i’到索引’j’的最短路径。

时间复杂度: O(N ^ 2)–顶点数为O(N ^ 2)

高效方法:

  1. 对于每个字符X ,找到与之相邻的所有字符。
  2. 创建一个图时,将节点数作为字符串中不同字符的数目,每个节点代表一个字符。
  3. 每个节点X,将具有权重1的边缘与表示相邻字符X字符的所有节点。
  4. 然后可以在这个新图中从代表S [i]的节点到代表S [j]的节点运行BFS

时间复杂度: O(N)

下面是上述方法的实现:

C++
// C++ implementation of the above approach.
#include 
using namespace std;
  
// function to find the minimum cost
int findMinCost(string s, int i, int j)
{
    // graph
    vector > gr(26);
  
    // adjacency matrix
    bool edge[26][26];
  
    // initialising adjacency matrix
    for (int k = 0; k < 26; k++)
        for (int l = 0; l < 26; l++)
            edge[k][l] = 0;
  
    // creating adjacency list
    for (int k = 0; k < s.size(); k++) {
        // pushing left adjacent elelemt for index 'k'
        if (k - 1 >= 0
            and !edge[s[k] - 97][s[k - 1] - 97])
            gr[s[k] - 97].push_back(s[k - 1] - 97),
                edge[s[k] - 97][s[k - 1] - 97] = 1;
        // pushing right adjacent element for index 'k'
        if (k + 1 <= s.size() - 1
            and !edge[s[k] - 97][s[k + 1] - 97])
            gr[s[k] - 97].push_back(s[k + 1] - 97),
                edge[s[k] - 97][s[k + 1] - 97] = 1;
    }
  
    // queue to perform BFS
    queue q;
    q.push(s[i] - 97);
  
    // visited array
    bool v[26] = { 0 };
  
    // variable to store depth of BFS
    int d = 0;
  
    // BFS
    while (q.size()) {
  
        // number of elements in the current level
        int cnt = q.size();
  
        // inner loop
        while (cnt--) {
  
            // current element
            int curr = q.front();
  
            // popping queue
            q.pop();
  
            // base case
            if (v[curr])
                continue;
            v[curr] = 1;
  
            // checking if the current node is required node
            if (curr == s[j] - 97)
                return d;
  
            // iterating through the current node
            for (auto it : gr[curr])
                q.push(it);
        }
  
        // updating depth
        d++;
    }
  
    return -1;
}
  
// Driver Code
int main()
{
    // input variables
    string s = "abcde";
    int i = 0;
    int j = 4;
  
    // function to find the minimum cost
    cout << findMinCost(s, i, j);
}


Java
// Java implementation of the above approach.
import java.util.*;
  
class GFG 
{
  
    // function to find the minimum cost
    static int findMinCost(char[] s, int i, int j) 
    {
        // graph
        Vector[] gr = new Vector[26];
        for (int iN = 0; iN < 26; iN++)
            gr[iN] = new Vector();
              
        // adjacency matrix
        boolean[][] edge = new boolean[26][26];
  
        // initialising adjacency matrix
        for (int k = 0; k < 26; k++)
            for (int l = 0; l < 26; l++)
                edge[k][l] = false;
  
        // creating adjacency list
        for (int k = 0; k < s.length; k++) 
        {
            // pushing left adjacent elelemt for index 'k'
            if (k - 1 >= 0 && !edge[s[k] - 97][s[k - 1] - 97]) 
            {
                gr[s[k] - 97].add(s[k - 1] - 97);
                edge[s[k] - 97][s[k - 1] - 97] = true;
            }
            // pushing right adjacent element for index 'k'
            if (k + 1 <= s.length - 1 && !edge[s[k] - 97][s[k + 1] - 97]) 
            {
                gr[s[k] - 97].add(s[k + 1] - 97);
                edge[s[k] - 97][s[k + 1] - 97] = true;
            }
        }
  
        // queue to perform BFS
        Queue q = new LinkedList();
        q.add(s[i] - 97);
  
        // visited array
        boolean[] v = new boolean[26];
  
        // variable to store depth of BFS
        int d = 0;
  
        // BFS
        while (q.size() > 0) 
        {
  
            // number of elements in the current level
            int cnt = q.size();
  
            // inner loop
            while (cnt-- > 0) 
            {
  
                // current element
                int curr = q.peek();
  
                // popping queue
                q.remove();
  
                // base case
                if (v[curr])
                    continue;
                v[curr] = true;
  
                // checking if the current node is required node
                if (curr == s[j] - 97)
                    return d;
  
                // iterating through the current node
                for (Integer it : gr[curr])
                    q.add(it);
            }
  
            // updating depth
            d++;
        }
  
        return -1;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        // input variables
        String s = "abcde";
        int i = 0;
        int j = 4;
  
        // function to find the minimum cost
        System.out.print(findMinCost(s.toCharArray(), i, j));
    }
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the above approach.
from collections import deque as a queue
  
# function to find minimum cost
def findMinCost(s, i, j):
      
    # graph
    gr = [[] for i in range(26)]
  
    # adjacency matrix
    edge = [[ 0 for i in range(26)] for i in range(26)]
  
    # initialising adjacency matrix
    for k in range(26):
        for l in range(26):
            edge[k][l] = 0
  
    # creating adjacency list
    for k in range(len(s)):
  
        # pushing left adjacent elelemt for index 'k'
        if (k - 1 >= 0 and edge[ord(s[k]) - 97][ord(s[k - 1]) - 97] == 0):
            gr[ord(s[k]) - 97].append(ord(s[k - 1]) - 97)
            edge[ord(s[k]) - 97][ord(s[k - 1]) - 97] = 1
  
        # pushing right adjacent element for index 'k'
        if (k + 1 <= len(s) - 1 and edge[ord(s[k]) - 97][ord(s[k + 1]) - 97] == 0):
            gr[ord(s[k]) - 97].append(ord(s[k + 1]) - 97)
            edge[ord(s[k]) - 97][ord(s[k + 1]) - 97] = 1
  
    # queue to perform BFS
    q = queue()
    q.append(ord(s[i]) - 97)
  
    # visited array
    v = [0] * (26)
  
    # variable to store depth of BFS
    d = 0
  
    # BFS
    while (len(q)):
  
        # number of elements in the current level
        cnt = len(q)
  
        # inner loop
        while (cnt > 0):
  
            # current element
            curr = q.popleft()
  
  
            # base case
            if (v[curr] == 1):
                continue
            v[curr] = 1
  
            # checking if the current node is required node
            if (curr == ord(s[j]) - 97):
                return curr
  
            # iterating through the current node
            for it in gr[curr]:
                q.append(it)
            print()
            cnt -= 1
  
        # updating depth
        d = d + 1
  
    return -1
  
# Driver Code
  
# input variables
s = "abcde"
i = 0
j = 4
  
# function to find the minimum cost
print(findMinCost(s, i, j))
  
# This code is contributed by mohit kumar 29


C#
// C# implementation of the above approach.
using System;
using System.Collections.Generic;
  
class GFG 
{
  
    // function to find the minimum cost
    static int findMinCost(char[] s, int i, int j) 
    {
        // graph
        List[] gr = new List[26];
        for (int iN = 0; iN < 26; iN++)
            gr[iN] = new List();
              
        // adjacency matrix
        bool[,] edge = new bool[26, 26];
  
        // initialising adjacency matrix
        for (int k = 0; k < 26; k++)
            for (int l = 0; l < 26; l++)
                edge[k, l] = false;
  
        // creating adjacency list
        for (int k = 0; k < s.Length; k++) 
        {
            // pushing left adjacent elelemt for index 'k'
            if (k - 1 >= 0 && !edge[s[k] - 97, s[k - 1] - 97]) 
            {
                gr[s[k] - 97].Add(s[k - 1] - 97);
                edge[s[k] - 97, s[k - 1] - 97] = true;
            }
              
            // pushing right adjacent element for index 'k'
            if (k + 1 <= s.Length - 1 && 
                !edge[s[k] - 97, s[k + 1] - 97]) 
            {
                gr[s[k] - 97].Add(s[k + 1] - 97);
                edge[s[k] - 97, s[k + 1] - 97] = true;
            }
        }
  
        // queue to perform BFS
        Queue q = new Queue();
        q.Enqueue(s[i] - 97);
  
        // visited array
        bool[] v = new bool[26];
  
        // variable to store depth of BFS
        int d = 0;
  
        // BFS
        while (q.Count > 0) 
        {
  
            // number of elements in the current level
            int cnt = q.Count;
  
            // inner loop
            while (cnt-- > 0) 
            {
  
                // current element
                int curr = q.Peek();
  
                // popping queue
                q.Dequeue();
  
                // base case
                if (v[curr])
                    continue;
                v[curr] = true;
  
                // checking if the current node is required node
                if (curr == s[j] - 97)
                    return d;
  
                // iterating through the current node
                foreach (int it in gr[curr])
                    q.Enqueue(it);
            }
  
            // updating depth
            d++;
        }
  
        return -1;
    }
  
    // Driver Code
    public static void Main(String[] args)
    {
        // input variables
        String s = "abcde";
        int i = 0;
        int j = 4;
  
        // function to find the minimum cost
        Console.Write(findMinCost(s.ToCharArray(), i, j));
    }
}
  
// This code is contributed by 29AjayKumar


输出:

4