Leetcode Study Day 3

Remove Duplicates from Sorted Array

Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements in nums.

Consider the number of unique elements of nums to be k, to get accepted, you need to do the following things:

  • Change the array nums such that the first k elements of nums contain the unique elements in the order they were present in nums initially. The remaining elements of nums are not important as well as the size of nums.
  • Return k.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Custom Judge:

    The judge will test your solution with the following code:

    int[] nums = [...]; // Input array
    int[] expectedNums = [...]; // The expected answer with correct length

    int k = removeDuplicates(nums); // Calls your implementation

    assert k == expectedNums.length;
    for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
    }
    If all assertions pass, then your solution will be accepted.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Example 1:

    Input: nums = [1,1,2]
    Output: 2, nums = [1,2,_]
    Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2 respectively.
    It does not matter what you leave beyond the returned k (hence they are underscores).
    Example 2:

    Input: nums = [0,0,1,1,1,2,2,3,3,4]
    Output: 5, nums = [0,1,2,3,4,_,_,_,_,_]
    Explanation: Your function should return k = 5, with the first five elements of nums being 0, 1, 2, 3, and 4 respectively.
    It does not matter what you leave beyond the returned k (hence they are underscores).


    Constraints:

    1 <= nums.length <= 3 * 104
    -100 <= nums[i] <= 100
    nums is sorted in non-decreasing order.

    My solution

    My idea is loop the whole array from the second element to the end. If the element is equal to the previous one, we remove this element by using array.erase(nums.begin()+ i ). Then we return the size of the array.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Solution {
    public:
    int removeDuplicates(vector<int>& nums) {
    for (int i = 1; i< nums.size(); i++){
    if (nums[i] == nums[i-1]){
    nums.erase(nums.begin()+i);
    i--;
    }
    if (i + 1 == nums.size())
    break;
    }
    int k = nums.size();
    return k;
    }
    };

    Remove Duplicates from Sorted Array II

    Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same.

Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.

Return k after placing the final result in the first k slots of nums.

Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra memory.

1
2
3
4
5
6
7
8
9
10
11
12
Example 1:

Input: nums = [1,1,1,2,2,3]
Output: 5, nums = [1,1,2,2,3,_]
Explanation: Your function should return k = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).
Example 2:

Input: nums = [0,0,1,1,1,1,2,3,3]
Output: 7, nums = [0,0,1,1,2,3,3,_,_]
Explanation: Your function should return k = 7, with the first seven elements of nums being 0, 0, 1, 1, 2, 3 and 3 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).

The difference between this question and the first question is that we need to keep the first two elements of the duplicated elements.

My solution

Actually, my idea is similar with my solution of the first question. Compare the previous two elements, if the current one is equal to them, than wo remove them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
for (int i = 2; i < nums.size(); i++){
if (nums[i] == nums[i-1] && nums[i] == nums[i-2]){
nums.erase(nums.begin() + i);
i --;
}
if (i + 1 == nums.size()){
break;
}
}
return nums.size();
}
};

Improved solution

ChatGPT shows me an idea of using two pointers. It says my original solution cost O(n^2) time complexity because the function erase need to loop the whole array. Here is its improved solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if (n <= 2) {
return n;
}

int count = 1; // Initialize the count of the current element to 1
int j = 1; // The pointer for the next available position in the array

for (int i = 1; i < n; i++) {
if (nums[i] == nums[i - 1]) {
count++;
} else {
count = 1; // Reset the count for the new element
}

if (count <= 2) {
nums[j++] = nums[i]; // Copy the element to the next available position
}
}

return j; // j now holds the length of the modified array
}
};

If the count is smaller than 2, which means for now, there are less than 2 duplicated elements, we can copy the element which in position j to the current element. Other wise, we just skip the operation of duplicating the jth element to the current element because there are already two elements in the array. The improved solution’s time complexity is O(n).

However, for this solution, the last element in the array will not be changed. Althought it doesn’t matter because the question only want the first j elements of the array.

  • Copyrights © 2020-2024 Yangyang Cui

请我喝杯咖啡吧~

支付宝
微信