シリーズ記事ディレクトリ
記事ディレクトリ
序文
プログラミングの世界ではデータ構造は非常に重要で、特に大きな工場での面接は必須項目です 今日は、ふとしたきっかけで【順序配列の重複を削除する】というお題が出てきたので、Javaコードで実装してみます。
1. トピック
配列番号を昇順で指定した場合、各要素が 1 回だけ表示されるように、繰り返される要素を所定の位置で削除し、削除された配列の新しい長さを返してください。要素の相対的な順序は一貫している必要があります。次に、一意の要素の数を nums で返します。
nums の一意の要素の数が k であることを考慮すると、ソリューションが確実に合格できるようにするには、次のことを行う必要があります。
- nums の最初の k 要素に、最初に nums に出現した順序で一意の要素が含まれるように、配列 nums を変更します。nums の残りの要素は、nums のサイズには影響しません。
- kを返します。
ソース: leetcode
リンク: https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
タイトル: 26. 順序付けられた配列内の重複を削除する
1.2. 判断基準
システムは次のコードを使用してソリューションをテストします。
int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
すべてのアサーションが合格すれば、ソリューションは合格します。
1.3. 例
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
2. 問題解決
2.1. ダブルポインタの前方参照
時間計算量は O(n) で、インプレース検索は追加のスペースを消費しません。
2.2. 解決策
1 つのポインタ i は配列の走査に使用され、もう 1 つのポインタ j は有効な配列の最後の位置を指します。
i が指す値が j と矛盾する (繰り返されない) 場合にのみ、i の値が j の次の位置に追加されます。
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
int j = 0;
for (int i = 0; i < n; i++) {
if (nums[i] != nums[j]) {
nums[++j] = nums[i];
}
}
return j + 1;
}
}
- 時間計算量: O(n)
- 空間の複雑さ: O(1)
2.2、逆の順序で削除する
この疑問は、ArrayList コレクション内のデータを Java で積極的に削除できない理由を導き出すことができます。
逆削除により、コレクション内のインデックス/値が変更されないことが保証され、時間計算量も O(n) になります
(逆削除の場合、他のデータのシーケンス番号の変更には影響しません)。
3. まとめ
この記事では、ダブル ポインターの前方検索アルゴリズムと逆削除アルゴリズムを使用して、配列内の重複を削除し、一意の数値の長さを返します。これら 2 つのアルゴリズムはいずれも余分なスペースを占有しません。