著者: Zhai Tianbao Steven
著作権表示: 著作権は著者に属します。商業的転載の場合は、許可について著者に連絡してください。非商業的な転載の場合は、出典を示してください。
タイトル説明:
整数配列では、1 回しか出現しない 2 つの数値を除き、他のすべての数値は 2 回出現します。一度しか出現しないこれら 2 つの数字を見つけるプログラムを作成してください。
データ範囲:配列の長さ 2≤n≤1000、配列内の各数値のサイズ 0<val≤1000000
要件:空間計算量 O(1)、時間計算量 O(n)
ヒント: 出力時に非降順で並べ替えます。
例:
入力:
[1,4,1,6]
戻り値:
[4,6]
例証します:
小さい方の数値を最初に返します
問題解決のアイデア:
この問題はビット演算について調べます。問題を解決する 2 つの方法。
1) 暴力の法則
ハッシュ テーブルを使用して出現頻度を記録し、頻度 1 の数値を出力します。この方法の空間の複雑さは、タイトルの要件を満たしていません。
2) XOR演算
XOR 演算は、2 つの数値が 0 に等しく、1 とは異なることを意味します。探している数字以外は 1 回出現し、他の数字は 2 回出現するため、これらの数値を XOR した後、その性質に応じて重複する数値を相殺し、1 回出現した数値のみを保持します。
4^1^2^1^2 など。4 は 100、1 は 001、2 は 010、4^1 は 101、^2 は 111、^1 は 110、^2 は 100 になります。は4です。
2 つの数値が 1 回出現する場合、結果はこれら 2 つの数値の XOR と等価になります。たとえば、4^1^2^1^2^3 の場合、最終結果は 111、つまり 4^3 になります。
このトピックでは、これら 2 つの数値を出力する必要があるため、111 をどのように分離するか? 4 と 3 で、特定のビットが同じでない場合、XOR 結果のビットは 1 になります。t を 001 から定義し、t を 111 で演算して、最初に 1 になるビット (111 の右端) を見つけます。は 1 で、00x の位置で数値 4 と数値 3 が異なることを示します。再度トラバースして、このビットの数値に従ってすべてのデータを分類すると、2 つのグループが得られます。数値 1 のグループは次のとおりです。 3、および番号 0 のグループ。グループの結果は 4 です。
このトピックは、このソリューションに合わせて作成されたものであると言わざるを得ません。。。各条件は完全に一致します
テストコード:
1) 暴力の法則
class Solution {
public:
// 寻找出现一次的数字
vector<int> FindNumsAppearOnce(vector<int>& nums) {
unordered_map<int,int> um;
vector<int> result;
// 遍历数组
int size = int(nums.size());
for(int i = 0; i < size; ++i){
um[nums[i]]++;
}
// 寻找出现频率为1的数
for(int i = 0; i < size; ++i){
{
if(um[nums[i]] == 1){
result.emplace_back(nums[i]);
}
}}
// 按大小顺序输出
if(result[0] < result[1]){
return result;
}
else{
return { result[1], result[0] };
}
}
};
2) XOR演算
class Solution {
public:
// 寻找出现一次的数字
vector<int> FindNumsAppearOnce(vector<int>& nums) {
vector<int> result{ 0, 0};
// 遍历数组进行异或运算
int temp = 0;
int size = int(nums.size());
for(int i = 0; i < size; ++i){
temp ^= nums[i];
}
// 找到两个数不相同的第一位
int t = 1;
while((t & temp) == 0){
t <<= 1;
}
// 再次遍历,将t位为1的数归为1组,为0的数归为1组,这样两组的异或运算得到的结果就是两个不重复数
for(int i = 0; i < size; ++i){
if((t & nums[i]) == 0){
result[0] ^= nums[i];
}
else{
result[1] ^= nums[i];
}
}
// 按大小顺序输出
if(result[0] < result[1]){
return result;
}
else{
return { result[1], result[0] };
}
}
};