zoukankan      html  css  js  c++  java
  • 854. K-Similar Strings

    问题:

    给定一个字符串A,每次交换其中两个字符,

    最后使得到字符串B,求最少交换次数。

    Example 1:
    Input: A = "ab", B = "ba"
    Output: 1
    
    Example 2:
    Input: A = "abc", B = "bca"
    Output: 2
    
    Example 3:
    Input: A = "abac", B = "baca"
    Output: 2
    
    Example 4:
    Input: A = "aabc", B = "abca"
    Output: 2
    
    Note:
    1 <= A.length == B.length <= 20
    A and B contain only lowercase letters from the set {'a', 'b', 'c', 'd', 'e', 'f'}
    

      

    解法:BFS

    状态:每次交换后得到的字符串。

    使用unordered_set来避免重复得到的字符串。

    最终要求的交换次数,即为queue的展开层数。

    本题中,重点:剪枝

    对下一个交换的字符 i,j 的选择:

    我们目的是最终找到字符串B

    那么尽量向B靠近的选择交换。

    • 首先确定 i:找到当前字符串cur和B不一致的字符。
    1  while(cur[i]==B[i]) i++;
    • 然后确定 j:j 从 i+1 开始,直到字符串结尾n
      • 其中,若要交换的 cur[j] -> i 却 != B[i],就没有靠近B去交换,那么不选择这种交换。
      • 另外,若要交换的两个字符 i 和 j 相同,那么交换没意义,也不选择这种交换。
    1 if(cur[j]!=B[i] || cur[i]==cur[j]) continue;

    代码参考:

     1 class Solution {
     2 public:
     3     void getidx(int mask, vector<int>& idx, int n) {
     4         idx.clear();
     5         for(int k=0; k<n; k++) {
     6             if((mask>>k)&1) idx.push_back(k);
     7             if(idx.size()==2) return;
     8         }
     9         return;
    10     }
    11     int kSimilarity(string A, string B) {
    12         int level = 0;
    13         int n = A.length();
    14         queue<string> q;
    15         unordered_set<string> visited;
    16         q.push(A);
    17         visited.insert(A);
    18         string cur, next;
    19         while(!q.empty()) {
    20             int sz = q.size();
    21             for(int k=0; k<sz; k++) {
    22                 cur = q.front();
    23                 q.pop();
    24                 if(cur == B) return level;
    25                 int i = 0;
    26                 while(cur[i]==B[i]) i++;
    27                 for(int j=i+1; j<n; j++) {
    28                     if(cur[j]!=B[i] || cur[i]==cur[j]) continue;
    29                     //only swap j which == target j
    30                     //can't swap i==j (Useless)
    31                     next = cur;
    32                     swap(next[i], next[j]);
    33                     if(visited.insert(next).second) {
    34                         q.push(next);
    35                     }
    36                 }
    37             }
    38             level++;
    39         }
    40         return -1;
    41     }
    42 };
  • 相关阅读:
    VS2019远程调试
    windows下使用redis-desktop-manager远程连接redis失败问题
    无法打开到SQL Server的连接 (Microsoft SQL Server, 错误:53) .
    由于管理员设置的策略,该磁盘处于脱机状态
    window下ping端口tcping
    dos命令远程登陆window server服务器并重启
    大二寒假作业之Android
    大二寒假作业之Android
    大二寒假作业之Android
    大二寒假作业之JavaWeb
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14498212.html
Copyright © 2011-2022 走看看