80. 順序付き配列 II 内の重複を削除します。
順序付けされた配列が与えられていますnums
。2回以上出現する要素が 2 回のみ出現するように、繰り返される要素をその場で削除し、削除後の配列の新しい長さを返してください。
追加の配列スペースを使用する代わりに、 -place、O(1) の追加スペースを使用して変更する必要があります。
説明:
戻り値が整数であるのに、出力される答えは配列であるのはなぜですか?
入力配列は「参照」によって渡されることに注意してください。これは、関数内の入力配列への変更が呼び出し元に表示されることを意味します。
内部動作は次のように想像できます。
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
例 1:
输入:
nums = [1,1,1,2,2,3]
输出:
5, nums = [1,1,2,2,3]
解释:
函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3。 不需要考虑数组中超出新长度后面的元素。
例 2:
输入:
nums = [0,0,1,1,1,1,2,3,3]
输出:
7, nums = [0,0,1,1,2,3,3]
解释:
函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3。不需要考虑数组中超出新长度后面的元素。
ヒント:
- 1 <= nums.length <= 3 * 10 4
- -10 4 <= nums[i] <= 10 4
- nums は昇順にソートされます
分析します:
- このアルゴリズムの疑問に直面して、2 番目のマスターは再び深く考え込んでしまいました。
- この質問は26. 順序付けされた配列内の重複を削除すると非常に似ていますが、異なる点は、この質問では同じ要素を最大 1 回繰り返すことができるという点です。
- 重複を削除したい場合は、マッピングテーブルなどのデータ構造を利用してカウントする方が直感的ですが、問題では一定レベルの余剰領域のみを使用できる必要があるため、機器に頼ることはできず、スキルに頼る必要があります。
- 質問には順序という非常に重要な情報があります。これは、同じ数字が隣り合うことを意味します。つまり、現在の添字と前の添字は最大でも同じ数字を持つことができます。現在の添字は前の添字と同じであると判断され、マークされた番号が同じ場合、つまり と が
nums[i]
同じnums[i - 2]
場合は要素を削除する必要があるかどうか、重複を迅速に判断できます。 - 要件はその場で変更することであるため、新しい配列の長さが必要です (戻り値自体にも新しい配列の長さが必要です)。また、トラバーサル添字、つまりダブル ポインターも必要です。は一度走査する必要があり、必要なのは一定レベルの追加スペースだけであり、非常に効率的です。
- また、配列要素が 3 個未満 (または配列長が 2 以下) の場合は、質問の意味を確実に満たしており、何も処理せずに直接返すことができます。
答え:
さび:
impl Solution {
pub fn remove_duplicates(nums: &mut Vec<i32>) -> i32 {
let n = nums.len();
if n <= 2 {
return n as i32;
}
let (mut slow, mut fast) = (2, 2);
while fast < n {
if nums[slow - 2] != nums[fast] {
nums[slow] = nums[fast];
slow += 1;
}
fast += 1;
}
return slow as i32;
}
}
行く:
func removeDuplicates(nums []int) int {
n := len(nums)
if n <= 2 {
return n
}
slow, fast := 2, 2
for fast < n {
if nums[slow-2] != nums[fast] {
nums[slow] = nums[fast]
slow++
}
fast++
}
return slow
}
c++:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
const int n = nums.size();
if (n <= 2) {
return n;
}
int slow = 2, fast = 2;
while (fast < n) {
if (nums[slow - 2] != nums[fast]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
};
パイソン:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
slow = 2
for fast in range(2, len(nums)):
if nums[fast] != nums[slow - 2]:
nums[slow] = nums[fast]
slow += 1
return slow
ジャワ:
class Solution {
public int removeDuplicates(int[] nums) {
final int n = nums.length;
if (n <= 2) {
return n;
}
int slow = 2, fast = 2;
while (fast < n) {
if (nums[slow - 2] != nums[fast]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
}
この記事を読んでいただきありがとうございます~
[いいね][集める][コメント]3連続へようこそ~
諦めるのは難しいことじゃないけど、続けるのはカッコいいですよね~
みんなで少しでも前進できれば幸いです毎日 ~
この記事は副司令官ホワイト ハットによって書かれています: https://le-yi.blog.csdn.net/元のブログ~