なぜ私のコードの行を変更すると、スタックオーバーフローを引き起こすのでしょうか?

Wentao王:

これは、[ユニオン・検索の問題]:https://leetcode.com/problems/similar-string-groups/

私は、行を変更した場合parents[find(j)] = i;parents[find(i)] = j;、コードはスタックオーバーフローが発生します。どうやらパスが再帰的find()メソッドにはあまりにも深いです。しかし、私は、この変更のメイクをしてどのような違いはわかりません。誰の助けができますか?

class Solution {
    int[] parents;
    public int numSimilarGroups(String[] A) {
        parents = new int[A.length];
        for(int i = 0;i < parents.length;i++) {
            parents[i] = i;
        }
        for(int i = 0;i < A.length;i++) {
            for(int j = 0;j < i;j++) {
                if(similar(A[i],A[j])) {
                    parents[find(j)] = i;
                }
            }
        }
        int ans = 0;
        for(int i = 0;i < parents.length;i++) {
            if(parents[i] == i)
                ans++;
        }
        return ans;
    }

    private int find(int curr) {
        int p = parents[curr];
        if(p != curr) {
            int pp = find(p);
            parents[curr] = pp;
        }
        return parents[curr];
    }

    private boolean similar(String a, String b) {
        int diff = 0;
        int i = 0;
        boolean consecutive = false;
        while(diff <= 2 && i < a.length()) {
            if(a.charAt(i) != b.charAt(i))
                diff++;
            if(i > 0 && a.charAt(i) == a.charAt(i-1))
                consecutive = true;
            i++;
        }
        return diff == 2 || diff == 0 && consecutive;
    }
}
ItsPete:

使用parents[find(i)] = j値がインデックスになることができる値を繰り返すことにより、インデックスよりも小さくなることを可能にします。これは、2つの要素が互いのインデックス/値を反転している状況をもたらすことができます。例えば:

与えられたA.length == 5、あなたの開始配列は次のようになります。

両親[0] = 0; 親[1] = 1。親[2] = 2; 親[3] = 3; 親[4] = 4。

私たちが使用する値は、のためになりsimilar、真を返します。以降ではi = 2, j = 1、これは電話をかけることになります。

find(2);    //Array doesn't change in recursive function

//Resulting array after applying j to parents[2]:
//          parents[0] = 0; parents[1] = 1; parents[2] = 1; parents[3] = 3; parents[4] = 4;

次に、i = 3, j = 1

find(3);    //Array doesn't change in recursive function

//Resulting array after applying j to parents[3]:
//          parents[0] = 0; parents[1] = 1; parents[2] = 1; parents[3] = 1; parents[4] = 4;

その後i = 3, j = 2

find(3); find(1);    //Array doesn't change in recursive function

//Resulting array after applying j to parents[1]:
//          parents[0] = 0; parents[1] = 2; parents[2] = 1; parents[3] = 1; parents[4] = 4;

あなたは(私たちは私たちの無限ループが設定されていることを今見ることができますparents[1] = 2; parents[2] = 1)。場合はfind1または2で呼び出され、これは、これらの2つの値の間で動けなくなります。我々はそこに着くために2つ以上のステップを必要としています。i = 4, j = 1

find(4);    //Array doesn't change in recursive function

//Resulting array after applying j to parents[1]:
//          parents[0] = 0; parents[1] = 2; parents[2] = 1; parents[3] = 1; parents[4] = 1;

最後に、i = 4, j = 2

find(4); find(1); find(2); find(1); find(2); find(1); find(2); ...

使用するparents[find(j)] = iために割り当てられた値が低くなることができないことを意味するiのに対し、常に刻みjの各反復のための反復をijの任意の値を指定できます0 to i -1

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=237031&siteId=1