目次
質問リンク: https://www.nowcoder.com/share/jump/819478881694767416272
トピックの説明:
繰り返し要素のない整数配列 nums が与えられた場合、その中に現れない最小の正の整数を見つけてください。
上級: 空間計算量 O(1)、時間計算量 O(n)
例1
入力: [1,0,2]
戻り値: 3
例 2
入力: [-2,3,4,1,5]
戻り値: 2
例 3
入力: [4,5,6,8,9]
戻り値: 1
分析します:
質問と与えられた 3 つの例を読んだ後、次の結論を導き出すことができます。
- 指定された配列内のデータはランダムな整数であり、順序付けされていません。
- 指定された配列内のデータには負の数値が含まれています。
- 戻り値は 1 以上である必要があります。
質問で必要な空間計算量は O(1)、時間計算量は O(n) であるため、空間の開きをできる限り減らすように努める必要があります。
この質問ではハッシュ テーブルを使用できますが、空間の複雑さは O(n) であるため、この方法は本当に解決策が思いつかない場合にのみ使用してください。
したがって、現時点では、上記の結論から始めることができます。配列は順序付けされていないため、最初にライブラリ メソッドを使用して配列を並べ替えることができます。
public int minNumberDisappeared (int[] nums) {
Arrays.sort(nums);
}
並べ替え後、アイデアがすぐに広がりました。配列には 0 以下の数値が含まれる可能性があるため、最初にループを使用してこの部分をスキップできます。
public int minNumberDisappeared (int[] nums) {
int ret = 0; //返回值
int len = nums.length; //数组长度
Arrays.sort(nums);
int i = 0; //记录数组遍历的位置
while (i < len && nums[i] <= 0) {
i++;
}
}
このとき、配列には0以上の数値しかありませんが、このときの判定は非常に簡単で、2つの数値の間に整数があるかどうかを直接判定し、あれば整数を返すことができます。 。配列が [1,2,3,4] の場合は、最後の数値に 1 を加えた値を返します。
while (i < len - 1) {
if (nums[i] + 1 < nums[i+1]) {
return nums[i] + 1;
}
i++;
}
ret = nums[len-1] + 1;
return ret;
最後に、質問を行うたびに欠かせないステップ、つまり限界値の判断に進みます。
次に、コードの先頭で配列を判断します。配列が存在しない場合は、最小の正の整数 1 を返します。
if (nums == null || nums.length == 0) {
return 1;
}
最初のループの後、配列に 1 が存在しないと判断され、1 が返されます。
if (nums[i] - 1 >= 1) {
return 1;
}
このとき、ライブラリ関数の計算量を無視すると、この問題で使用する計算量は、空間計算量 O(1)、時間計算量 O(n) となります。
完全なコード:
import java.util.*;
public class Solution {
public int minNumberDisappeared (int[] nums) {
// write code here
if (nums == null || nums.length == 0) {
return 1;
}
int ret = 0;
int len = nums.length;
Arrays.sort(nums);
int i = 0;
while (i < len && nums[i] <= 0) {
i++;
}
if (nums[i] - 1 >= 1) {
return 1;
}
while (i < len - 1) {
if (nums[i] + 1 < nums[i+1]) {
return nums[i] + 1;
}
i++;
}
ret = nums[len-1] + 1;
return ret;
}
}