このセクションでは、ページ448タイトルの「電源ボタン」を共有することです:すべてがデジタルの配列消え見つけプラクティスを。
の範囲を考えます ( 整数配列の配列)のサイズであり、アレイ内のいくつかの要素がある他のものは一度だけ表示されている間、2回出現。
トピックに私たちを必要とします。
1、すべてで見つかりました の数字は、配列の範囲には表示されません。
2、あなたは余分なスペースと時間の複雑さを使用することはできません その場合には、このタスクを完了するために?あなたは、配列が余分なスペースに戻っていることを前提とすることはできません。
タイトルは、例を与える:入力配列です。[4, 3, 2, 7, 8, 2, 3, 1]
その長さ
、被験者の意味に応じて、範囲内の値の配列[1, 8]
。から会社
始めました
一つ一つは、彼らがデジタル発見しました
と
登場
回デジタル
と
、それぞれ、登場します
回。したがって、 [5, 6]
出力:。
出典:滞在ボタン(LeetCode)
//leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array:リンク:httpsの
すべてのネットワークからの控除が著作権を保有。商業転載は、ソースを明記してください許可公式、非商用の転載をご連絡ください。
アイデアの分析:
1は、経験の最初の41個の質問で、タイトルは私たちにフィギュアの範囲を伝える[1, n]
ので、まだ回数を横断し、ハッシュテーブルとして配列自体、することができ、我々は位置に配置する必要があり、それの上に置きます。問題解決のこの考え方によると、
このアイデアは、線形時間複雑に沿ったものです 必要。
2、タイトルにも余分なスペースを使用しないように私たちを尋ねました。我々は2つの配列要素を交換する過程で、この制限を行いますので、どのように、余分なスペースを使用する必要があることを知っています。これは、ある程度の知識と経験ビット・コンピューティングを取ります。私は、経験し、これは突然のすべてが、このアプローチを期待していなかった場合も、実際には問題ではないと考えるのは簡単で、実際にはないことをその意味する必要は述べています。
- 二つの変数の交換特性のXOR演算値を使用します。
このプロパティは、実際にXOR XOR演算の定義そのものです。XOR演算は、このように、キャリーバイナリ加算器ではないので。
(1)の場合a ^ b = c
、次にこれによって確立された同一の時間は、二つの変数の値を交換するために使用することができます。a ^ c = b
b ^ c = a
(2)多数のnum
異なるまたは同一の番号(a
)
回、その値はnums ^ a ^ a = num
変わりません:。
そして、二つの変数の切り替え値は、例えばa
、そしてb
、3番目の変数を使用せずに、これを行うことができます。
a = a ^ b
b = a ^ b
a = a ^ b
その真実はこれです:
最初の番号 | ナンバー2 |
---|---|
a |
b |
ab |
b |
ab |
a |
b |
a |
しかし、このアプローチは、ピットを持っており、私たちが言ってこの質問を終了します。
私たちは、具体例の分析を使用します。
- 私たちの目標は、することがある
nums[i]
インデックスにあるnums[i] - 1
場所に。
最良の方法は次のとおりです。
値:[1, 2, 3, 4]
;
インデックス:[0, 1, 2, 3]
。
説明:値を取ることができます4
マークされた上で3
の指標値の位置、長さ位置持つ1
オフセットを。
現在のトラバーサルを参照してくださいと仮定nums[i]
することを4
我々はのインデックス位置を調べる必要があり3
要素が上にありません4
。
配列インデックスの場合(1)3
位置番号ではない4
、電流が参照する必要がある4
配列添え字に切り替え3
上の位置。
(2)インデックス位置であれば3
、すでに上の4
、そして現在は見る4
それを無視しないでください、それはこの時点では何もしない、不必要である、数を見続けています。
nums[i]
番号であり、nums[i] - 1
インデックス位置を示しています。
(あなたは文言余分なスペースを使用することができます)
Javaコード:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
int len = nums.length;
List<Integer> res = new ArrayList<>(2);
for (int i = 0; i < len; i++) {
// 数字 4 应该在下标 3 的位置上
while (nums[i] != nums[nums[i] - 1]) {
swap(nums, i, nums[i] - 1);
}
}
for (int i = 0; i < len; i++) {
if (nums[i] != i + 1) {
res.add(i + 1);
}
}
return res;
}
private void swap(int[] nums, int index1, int index2) {
int temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
}
(文言余分なスペースを使用しないでください)
Javaコード:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> res = new ArrayList<>(2);
for (int i = 0; i < nums.length; i++) {
// 数字 4 应该在下标 3 的位置上
while (nums[i] != nums[nums[i] - 1]) {
swap(nums, i, nums[i] - 1);
}
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] != i + 1) {
res.add(i + 1);
}
}
return res;
}
private void swap(int[] nums, int index1, int index2) {
if (index1 == index2) {
return;
}
nums[index1] = nums[index1] ^ nums[index2];
nums[index2] = nums[index1] ^ nums[index2];
nums[index1] = nums[index1] ^ nums[index2];
}
public static void main(String[] args) {
Solution7 solution7 = new Solution7();
int[] nums = {4, 3, 2, 7, 8, 2, 3, 1};
List<Integer> res = solution7.findDisappearedNumbers(nums);
System.out.println(res);
}
}