配列内の数値メソッドの消失または繰り返しを見つける

序文

Likou.comで配列内の欠落している数字と繰り返されている数字を見つけることについて、いくつかの連続した質問を書きましたが、解決策のいくつかは本当に微妙すぎることがわかりました。それから波を記録してください~~~~ナンセンスな話をしないで、始めましょう!

剣はオファー03を指します。配列内の繰り返し番号

配列内の繰り返し番号を見つけます。

長さnの配列nums内のすべての数値は、0〜n-1の範囲です。配列内のいくつかの数字が繰り返されますが、何回繰り返されるか、また各数字が何回繰り返されるかはわかりません。配列内で重複する番号を見つけてください。
オリジナルのタイトルポータル
ここに画像の説明を挿入

1.ハッシュテーブル方式

ハッシュテーブルを使用して表示された番号を記録し、配列をトラバースしているときにその番号がハッシュテーブルに存在するかどうかを確認します

class Solution {
    
    
public:
    int findRepeatNumber(vector<int>& nums) {
    
    
        unordered_set<int> historyNums;
        for(auto& p:nums){
    
    
            if(!historyNums.count(p))
                historyNums.insert(p);
            else return p;
        }
        return -1;
    }
};

1つのトラバーサルでは、時間計算量はO(N)であり、ハッシュの追加スペースが使用され、スペース複雑度はO(N)です。

2.表記

独創的なことは、numsのすべての数値0〜n-1の範囲にあることです。これは、長さnの配列の添え字に対応します。配列の要素を添え字として使用する場合は、この数値に1を追加します。トラバーサルプロセス中に数値がn-1より大きいことが判明した場合、その数値は以前にマークされていることを意味します。したがって、下付き文字の対応する値は、検索する必要のある繰り返しの数値です。

class Solution {
    
    
public:
    int findRepeatNumber(vector<int>& nums) {
    
    
        int len=nums.size();
        for(auto& p:nums){
    
    
            int index=p % len;
            if(nums[index]>=len) 
            	return index;
            nums[index] += len;
        }
        return -1;
    }
};

1つのトラバーサルでは、時間計算量はO(N)であり、一定の空間が使用され、空間計算量はO(1)です。

448.配列内の欠落しているすべての番号を検索します

1≤a [i]≤n(n =配列サイズ)の範囲の整数配列が与えられた場合、配列内の一部の要素は2回表示され、一部は1回だけ表示されます。

配列に表示されない範囲[1、n]のすべての数値を見つけます。

余分なスペースを使用せずにこのタスクを実行でき、時間計算量はO(n)ですか?返された配列は余分なスペースに含まれていないと想定できます。
オリジナルタイトル送信
ここに画像の説明を挿入

表記

なじみのある感じですか?はい、配列内の要素の値は1〜nの間にあり、配列の添え字0〜n -1とは1異なります。したがってこれらの要素の1つを引いた値を引き続き使用できます。マークを付けた後、再び配列をトラバースします。0より大きい数値が見つかった場合、その数値はマークされていないことを意味し、添え字の値に1を加えたものに対応する数値は間違いなく配列に含まれていません(それは厄介です、多分コードはより良いですいくつかを理解してください)

class Solution {
    
    
public:
	vector<int> findDisappearedNumbers(vector<int>& nums) {
    
    
		int n = nums.size();
		for (int i = 0; i < n; i++) {
    
    //遍历数组进行标记
			int index = abs(nums[i]) - 1;//下标需要取绝对值,因为有些元素被标记成了负数
			if (nums[index] > 0)//已经被标记过一次的数就不需要再次标记
				nums[index] = 0 - nums[index];
		}

		vector<int> res;
		for (int i = 0; i < n; i++)
			if (nums[i] > 0)
				res.push_back(i + 1);

		return res;
	}
};

最初にここに行き、更新を続けてください~~~

おすすめ

転載: blog.csdn.net/Genius_bin/article/details/113803055