854. K-Similar Strings

在这里插入图片描述

回溯法还是比较好理解的,但是遗憾自己没有写出来。

class Solution {
public:
    int kSimilarity(string A, string B) {
        unordered_map<string, int> memo;
        return backtrack(A, B, memo, 0);
    }
private:
    int backtrack(string& A, string& B, unordered_map<string, int>& memo, int i) {//不用i也可以
        if (A == B)
            return 0;
        if (memo.find(A) != memo.end())
            return memo[A];
        while (i < A.size() && A[i] == B[i])
            ++i;
        int minVal = INT_MAX;
        for (int j = i; j < A.size(); ++j) {
            if (A[j] == B[i]) {
                swap(A[i], A[j]);
                int next = backtrack(A, B, memo, i+1);
                if (next != INT_MAX)
                    minVal = min(minVal, next+1);
                swap(A[i], A[j]);
            }
        }
        memo[A] = minVal;
        return minVal;
    }
};

还是那句话,回溯就是试验所有可能性。

还有一个应该想出来的方法,遗憾没有想出来:

class Solution {
public:
    int kSimilarity(string A, string B) {
        if (A == B)
            return 0;
        queue<string> q;
        unordered_set<string> visited;
        q.push(A);
        int level = 0;
        while (!q.empty()) {
            level++;
            int sz = q.size();
            while (sz--) {
                auto str = q.front();
                q.pop();
                if (visited.find(str) != visited.end())
                    continue;
                visited.insert(str);
                int i = 0;
                while (i < str.size() && str[i] == B[i])
                    ++i;
                //assert(i != str.size());
                for (int j = i+1; j < str.size(); ++j) {
                    if (str[j] == B[i]) {
                        swap(str[i], str[j]);
                        if (visited.find(str) != visited.end())
                            continue;
                        if (str == B)
                            return level;
                        q.push(str);
                        swap(str[i], str[j]);
                    }
                }//我这里是把第一对不符合的给干掉了,而且全部情况
            }//还有其他可能是:把所有可能在一步可以完成的交换全部完成。但是这里没有必要,因为最后总会全部交换完成,这样一步一步是必须的。
        }
        return 0;
    }
};
//最短:想到bfs
//然后怎么算有链接:想到之前有题目是换一个字母相当于有链接
//这里是交换一对字母可以算是有连接
posted @ 2019-10-24 10:15  于老师的父亲王老爷子  阅读(23)  评论(0编辑  收藏  举报