文字列javaの要素を交換する

文字列sと、文字列内のいくつかの「インデックスペア」配列ペアを指定します。ここで、pairs [i] = [a、b]は、文字列内の2つのインデックスを表します(番号は0から始まります)。

インデックスの任意のペアの文字を、ペアで何度でも交換できます。

sが数回の交換後になり得る最小の文字列を辞書式に返します。

例1:

入力:s = "dcab"、ペア= [[0,3]、[1,2]]
出力: "bacd"
説明:
交換s [0]およびs [3]、s = "bcad"
交換s [1 ]およびs [2]、s = "bacd"
例2:

入力:s = "dcab"、ペア= [[0,3]、[1,2]、[0,2]]
出力: "abcd"
説明:
s [0]とs [3]を交換します。s = " 「bcad」は
s [0]とs [2]を
交換し、s = "acbd"はs [1]とs [2]を交換します。s = "abcd"
例3:

入力:s = "cba"、ペア= [[0,1]、[1,2]]
出力: "abc"
説明:
s [0]とs [1]を
交換します。s= "bca"はs [1を交換します。 ]およびs [2]、s = "bac"
交換s [0]およびs [1]、s = "abc"

促す:

1 <= s.length <= 10 ^ 5
0 <= pairs.length <= 10 ^ 5
0 <= pair [i] [0]、pairs [i] [1] <s.lengths
には小文字の英語のみが含まれます

出典:LeetCode
リンク:https ://leetcode-cn.com/problems/smallest-string-with-swaps
著作権はLeetCodeが所有しています商用の再版については、公式の承認に連絡してください。非商用の再版については、出典を示してください。

アイデア:私は無駄です。この質問は書きませんでした。もともと文字列操作を実行したかったのですが、10分ほど考えたときに、文字列を書くことができても複雑すぎるため、文字列を無効にしました。後でこの質問は大丈夫だと思いました。コレクションの使用と確認は、前回コピーしたテンプレートを配置するようなものですが、挿入しないと、emmmmはまだ良すぎます。
ps:誰かがコメントエリアにコメントを投稿した場合、私はそれを直接コピーしました

class Solution {
    
    
    public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
    
    
        //初始化连通图
        DisjointSetUnion dsu = new DisjointSetUnion(s.length());
        for(List<Integer> pair:pairs){
    
    
            //合并
            dsu.unionSet(pair.get(0),pair.get(1));
        }
        //使用map存储祖先节点到子节点列表的映射,存储并查集结果
        //例如s = "dcab", pairs = [[0,3],[1,2]]
        //0:[d,b]  1:[c,a]
        Map<Integer,List<Character>> map =new HashMap<Integer,List<Character>>();
        for(int i =0;i<s.length();i++){
    
    
            int parent = dsu.find(i);//找到该节点的父节点
            if(!map.containsKey(parent)){
    
    
                map.put(parent,new ArrayList<Character>());
            }
            map.get(parent).add(s.charAt(i));
        }
        //对map中的值进行排序
        for(Map.Entry<Integer,List<Character>> entry:map.entrySet()){
    
    
            Collections.sort(entry.getValue(),new Comparator<Character>(){
    
    
                public int compare(Character c1,Character c2){
    
    
                    return c2-c1;
                }
            });
        }
        StringBuffer sb = new StringBuffer();
        for(int i =0;i<s.length();i++){
    
    
            int x = dsu.find(i);
            List<Character> list =map.get(x);
            sb.append(list.remove(list.size()-1));
        }
        return sb.toString();

    }
}
//定义并差集类
class DisjointSetUnion{
    
    
    int n;  //并查集长度
    int[] rank;  //节点等级
    int[] f;   //存储对应的祖先节点

    //构造函数,初始化属性
    public DisjointSetUnion(int n){
    
    
        this.n = n;
        rank = new int[n];
        Arrays.fill(rank,1);
        f = new int[n];
        for(int i=0;i<n;i++){
    
    
            f[i] = i;
        }
    }

    //方法find,寻找给节点的祖先
    public int find(int x){
    
    
        return f[x] == x?x:(f[x]=find(f[x]));
    }

    //合并到一个图中,共同有一个祖先
    public void unionSet(int x, int y) {
    
    
        int fx=find(x),fy = find(y);
        if(fx==fy){
    
    
            return;
        }
        if(rank[fx]<rank[fy]){
    
    
            //swap(fx,fy);
            int temp = fx;
            fx=fy;
            fy=temp;
        }
        //fx级别高,要作为祖先
        rank[fx] +=rank[fy];
        f[fy] = fx;
    }

}

おすすめ

転載: blog.csdn.net/weixin_43824233/article/details/112471852
おすすめ