字符串互换后字典序最小

问题:给出一个字符串,以及可以互换的位置对,求出互换后字典序最小的。

比如给出字符串dcab,以及可以互换的位置对[[0,3],[1, 2],[0, 2]],则互换后字典序最小的是abcd

思路:第一种方法是广度优先搜索,初始状态为dcab,将初始状态放入队列以及已经访问状态集合中,根据可以互换的位置对扩展新的状态,同时需要记录已经访问的状态。如果新的状态在已访问状态集合中则跳过。代码如下:

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <queue>

using namespace std;

struct State
{
    string s;
    bool operator<(const State& other) const
    {
        return s < other.s;
    }

    bool operator==(const State& other) const
    {
        return s == other.s;
    }
};

class Solution
{
public:
    Solution(string& str, vector<vector<int>>& otherPairs)
        : s(str), pairs(otherPairs)
    {

    }

    string solve()
    {
        State initialState;
        initialState.s = s;
        set<State> visited;
        queue<State> queue;

        visited.insert(initialState);
        queue.push(initialState);
        string ans = s;
        while (!queue.empty())
        {
            State curState = queue.front(); queue.pop();

            for (auto& pair : pairs)
            {
                State newState = curState;
                char ch = newState.s[pair[0]];
                newState.s[pair[0]] = newState.s[pair[1]];
                newState.s[pair[1]] = ch;

                if (visited.count(newState))
                {
                    continue;
                }

                visited.insert(newState);
                queue.push(newState);
                if (newState.s < ans)
                {
                    ans = newState.s;
                }
            }
        }

        return ans;
    }

private:
    string& s;
    vector<vector<int>>& pairs;
};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string s = "dcab";
    vector<vector<int>> pairs = {{0, 3}, {1, 2}, {0, 2}};

    Solution solution(s, pairs);
    string ans = solution.solve();
    cout << ans << endl;

    return 0;
}

第二种方法使用并查集,将属于同一组的排序。根据不同组排序后的结果再作合并。

代码如下:

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>

using namespace std;

class DisjointSet
{
public:
    DisjointSet(const string& otherStr)
        : s(otherStr)
    {
        for (size_t i = 0; i < s.length(); ++i)
        {
            parent[i] = i;
            rank[i] = 0;
        }
    }

    int Find(int x)
    {
        return parent[x] == x ? x : parent[x] = Find(parent[x]);
    }

    void Union(int x, int y)
    {
        int px = Find(x);
        int py = Find(y);

        if (px != py)
        {
            if (rank[px] < rank[py])
            {
                parent[px] = py;
            }
            else
            {
                parent[py] = px;
                if (rank[px] == rank[py])
                {
                    rank[px] += 1;
                }
            }
        }
    }

    void getComponents(map<int, vector<int>>& components)
    {
        for (size_t i = 0; i < s.length(); ++i)
        {
            int p = Find(parent[i]);
            components[p].push_back(i);
        }
    }

private:
    const string& s;
    map<int, int> parent;
    map<int, int> rank;
};

class CmpStr
{
public:
    CmpStr(const string& others)
        : s(others)
    {

    }

    bool operator()(int x, int y)
    {
        return s[x] < s[y];
    }

private:
    const string& s;
};

class Solution
{
public:
    Solution(string& str, vector<vector<int>>& otherPairs)
        : s(str), pairs(otherPairs)
    {

    }

    string solve()
    {
        DisjointSet disjointSet(s);
        for (auto& pair : pairs)
        {
            disjointSet.Union(pair[0], pair[1]);
        }

        map<int, vector<int>> components;
        disjointSet.getComponents(components);

        string ans = s;
        for (auto& component : components)
        {
            auto src = component.second;
            sort(src.begin(), src.end());

            auto dst = component.second;
            sort(dst.begin(), dst.end(), CmpStr(s));

            for (size_t i = 0; i < src.size(); ++i)
            {
                ans[src[i]] = s[dst[i]];
            }
        }

        return ans;
    }

private:
    string& s;
    vector<vector<int>>& pairs;
};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string s = "dcab";
    vector<vector<int>> pairs = {{0, 3}, {1, 2}, {0, 2}};

    Solution solution(s, pairs);
    string ans = solution.solve();
    cout << ans << endl;

    return 0;
}
发布了1365 篇原创文章 · 获赞 71 · 访问量 140万+

猜你喜欢

转载自blog.csdn.net/wuli2496/article/details/105620793