📌  相关文章
📜  通过避免一组给定的字符串来获得给定的数字字符串的最小圆周旋转

📅  最后修改于: 2021-04-23 18:42:30             🧑  作者: Mango

给定的长度为N的数字字符串目标和一组数字字符串的堵塞,每一个的长度为N,则任务是找到圆形旋转的最小数目需要转换的初始字符串只由0“通过避免任何的s到目标出现的字符串在任何步骤都被阻止。如果不可能,请打印-1。
注意:单次旋转涉及将特定索引处的值增加或减少1个单位。由于旋转是圆形的,因此可以将0转换为9或将9转换为0。
例子:

方法:为了解决此问题,我们使用以下BFS方法:

  • 创建一个长度为N的字符串,开头仅包含0。将其推入队列。创建队列是为了存储一个可能的下一个有效组合,方法是按一个单位增加或减少一个字符。
  • 创建一个无序的集合规避,并在其中添加所有被阻止的字符串。
  • 如果在prevent中存在starttarget ,则无法达到所需的目标。
  • 从队列中弹出start并遍历start的所有字符。以一个单位增加和减少每个字符,并保持其余常数不变,并检查是否在避免字符串中。如果不是,并且新的组合不等于目标,请将其推入队列并插入以避免避免将来重复相同的组合。
  • 一旦遍历了整个起始长度,请对下一个级别重复上述步骤,这些步骤是从起始处获得的有效字符串,当前存在于队列中。
  • 继续重复上述步骤,直到达到目标或没有其他组合并且队列变空。
  • 在任何时候,如果形成的字符串等于目标,则返回count的值,该值将保留对BFS遍历级别数的计数。 count的值是所需的最小圆周旋转数。
  • 如果无法获得进一步的状态并且队列为空,请打印“不可能”

下面是上述逻辑的实现:

C++
// C++ Program to count the minimum
// number of circular rotations required
// to obtain a given numeric strings
// avoiding a set of blocked strings
 
#include 
using namespace std;
 
int minCircularRotations(
    string target,
    vector& blocked,
    int N)
{
    string start = "";
    for (int i = 0; i < N; i++) {
        start += '0';
    }
 
    unordered_set avoid;
 
    for (int i = 0; i < blocked.size(); i++)
        avoid.insert(blocked[i]);
 
    // If the starting string needs
    // to be avoided
    if (avoid.find(start) != avoid.end())
        return -1;
 
    // If the final string needs
    // to be avoided
    if (avoid.find(target) != avoid.end())
        return -1;
 
    queue qu;
    qu.push(start);
 
    // Variable to store count of rotations
    int count = 0;
 
    // BFS Approach
    while (!qu.empty()) {
 
        count++;
 
        // Store the current size
        // of the queue
        int size = qu.size();
 
        for (int j = 0; j < size; j++) {
 
            string st = qu.front();
            qu.pop();
 
            // Traverse the string
            for (int i = 0; i < N; i++) {
 
                char ch = st[i];
 
                // Increase the
                // current character
                st[i]++;
 
                // Circular rotation
                if (st[i] > '9')
                    st[i] = '0';
 
                // If target is reached
                if (st == target)
                    return count;
 
                // If the string formed
                // is not one to be avoided
                if (avoid.find(st)
                    == avoid.end())
                    qu.push(st);
 
                // Add it to the list of
                // strings to be avoided
                // to prevent visiting
                // already visited states
                avoid.insert(st);
 
                // Decrease the current
                // value by 1 and repeat
                // the similar checkings
                st[i] = ch - 1;
 
                if (st[i] < '0')
                    st[i] = '9';
                if (st == target)
                    return count;
                if (avoid.find(st)
                    == avoid.end())
                    qu.push(st);
                avoid.insert(st);
 
                // Restore the original
                // character
                st[i] = ch;
            }
        }
    }
 
    return -1;
}
 
// Driver code
int main()
{
    int N = 4;
    string target = "7531";
    vector blocked
        = { "1543",
            "7434",
            "7300",
            "7321",
            "2427" };
 
    cout << minCircularRotations(
                target,
                blocked, N)
         << endl;
 
    return 0;
}


Java
// Java Program to count the minimum
// number of circular rotations required
// to obtain a given numeric Strings
// avoiding a set of blocked Strings
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
 
class GFG
{
  static int minCircularRotations(String target,
                                  ArrayList blocked,
                                  int N)
  {
    String start = "";
    for (int i = 0; i < N; i++)
    {
      start += '0';
    }
 
    HashSet avoid = new HashSet<>();
    for (int i = 0; i < blocked.size(); i++)
      avoid.add(blocked.get(i));
 
    // If the starting String needs // to be avoided
    if (avoid.contains(start))
      return -1;
 
    // If the final String needs // to be avoided
    if (avoid.contains(target))
      return -1;
    Queue qu = new LinkedList<>();
    qu.add(start);
 
    // Variable to store count of rotations
    int count = 0;
 
    // BFS Approach
    while (!qu.isEmpty())
    {
      count++;
 
      // Store the current size // of the queue
      int size = qu.size();
      for (int j = 0; j < size; j++)
      {
        StringBuilder st = new StringBuilder(qu.poll());
 
        // Traverse the String
        for (int i = 0; i < N; i++)
        {
          char ch = st.charAt(i);
 
          // Increase the // current character
          st.setCharAt(i, (char) (st.charAt(i) + 1));
 
          // Circular rotation
          if (st.charAt(i) > '9')
            st.setCharAt(i, '0');
 
          // If target is reached
          if (st.toString().equals(target))
            return count;
 
          // If the String formed
          // is not one to be avoided
          if (!avoid.contains(st.toString()))
            qu.add(st.toString());
 
          // Add it to the list of
          // Strings to be avoided
          // to prevent visiting
          // already visited states
          avoid.add(st.toString());
 
          // Decrease the current
          // value by 1 and repeat
          // the similar checkings
          st.setCharAt(i, (char) (ch - 1));
          if (st.charAt(i) < '0')
            st.setCharAt(i, '9');
          if (st.toString().equals(target))
            return count;
          if (!avoid.contains(st.toString()))
            qu.add(st.toString());
          avoid.add(st.toString());
 
          // Restore the original
          // character
          st.setCharAt(i, ch);
        }
      }
    }
    return -1;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int N = 4;
    String target = "7531";
    ArrayList blocked =
      new ArrayList<>(Arrays.asList("1543",
                                    "7434",
                                    "7300",
                                    "7321",
                                    "2427"));
    System.out.println(minCircularRotations(target, blocked, N));
  }
}
 
// This code is contributed by sanjeev2552


输出:
12