Huawei マシンのテスト - 配列内の 2 つの異なる数値を見つける

(上級) 配列内の数値はすべて同じで、異なるのは 2 つだけであることがわかっているので、これら 2 つの数値を求めます。

ここでは 3 つのメソッドも提供されています。最初の 2 つは前のメソッドと似ており、3 つ目は XOR 演算の習熟が必要です。

解決策 1 (時間の複雑さが高い)

アイデア: for ループの 2 層。数値がそれ自体と同じ数値に到達しない場合は、その数値を記録します。それ以外の場合は、ループを終了し、次の番号のトラバースを続けます。
時間計算量: O( n 2 n^2n2 )
空間の複雑さ: O(1)

解決策 2 (空間の複雑性が高い)

アイデア: 辞書を使用します。辞書キーに数字が含まれていない場合は、その数字を辞書に追加します。そうでない場合は、キー値を削除します (任意の値、未使用)。最終的に、キー値は 2 つだけ残ります。これを出力します。 2 つのキー。
時間計算量: O(n)
空間計算量: O(n)

解決策 3 (最良)

アイデア: グループ化された XOR を使用します。前の質問よりも数値が 1 つ多いため、最初の XOR を 1 つずつ実行した後、これら 2 つの異なる数値の XOR 値しか取得できません。したがって、グループ XOR を実行し、2 つの異なる数値を 2 つのグループに分割し、それらを次々に XOR する必要があります。これは前の質問と同じになります。

スウィフトコード:

func findDifferentTwoNum(_ array: [Int]) -> [Int] {
    
    
    var res = Array<Int>()  //存放结果的数组
    var tmp = 0             //第一次数组逐个异或的结果,最终结果为:唯一两个不同数的异或值
    var rightMove = 0       //为了将两个不同数进行分组,找到tmp哪一位为1(异或值不同为1,说明这两个数在这一位不相同)
    var num1 = 0            //两个不同数其中一个
    var num2 = 0            //两个不同数另一个
    /**
     第一次数组逐个异或的结果
     最终结果tmp为:唯一两个不同数的异或值
     */
    for i in 0..<array.count{
    
    
        tmp = tmp ^ array[i]
    }
    /**
     tmp逐次右移
     找到tmp哪一位为1
     异或为1,说明那两个不同的数在该位上不相同,以此作为区分,将两个不同的数分到不同的组中去
     例如:rightMove:1 说明tmp右移一位,两个不同的数在第二位出现不同
     */
    while((tmp & 1) == 0){
    
    
        tmp = tmp >> 1
        rightMove += 1
    }
    /**
     ((array[i] >> rightMove) & 1)来进行分组,这两个不同的数结果一个为0,一个为1
     */
    for i in 0..<array.count{
    
    
        if(((array[i] >> rightMove) & 1) == 1){
    
    
            num1 = num1 ^ array[i]
        }else{
    
    
            num2 = num2 ^ array[i]
        }
    }
    /*
     最后分离出两个数
     */
    res.append(num1)
    res.append(num2)
    return res
}

時間計算量: O(n)
空間計算量: O(1)

おすすめ

転載: blog.csdn.net/weixin_44758107/article/details/127635990