📌  相关文章
📜  Java程序通过避免一组给定字符串来查找最小循环旋转以获得给定数字字符串

📅  最后修改于: 2022-05-13 01:54:21.825000             🧑  作者: Mango

Java程序通过避免一组给定字符串来查找最小循环旋转以获得给定数字字符串

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

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

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

下面是上述逻辑的实现:

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

请参阅关于最小圆形旋转的完整文章,通过避免一组给定的字符串来获得给定的数字字符串以获取更多详细信息!