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

📅  最后修改于: 2021-09-07 04:45:35             🧑  作者: Mango

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

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

  • 创建一个长度为N的字符串开始,仅由 0 组成。将其推入队列。创建队列以通过将字符增加或减少一个单位来存储下一个可能的有效组合。
  • 创建一个无序集合avoid ,并在其中添加所有被阻止的字符串。
  • 如果避免中存在starttarget ,则无法达到所需的目标。
  • 从队列中弹出start并遍历start 的所有字符。将每个字符增加和减少一个单位,保持剩余不变,并检查该字符串是否存在于avoid 中。如果不是,并且新组合不等于目标,则将其推入队列并插入避免以防止将来重复相同的组合。
  • 一旦遍历完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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live