[data structure and algorithm] in-depth analysis of the solution idea and algorithm example of "deleting duplicates in ordered arrays"

Posted by priya_amb on Tue, 25 Jan 2022 05:27:06 +0100

1, Title Requirements

  • Give you an ordered array nums, please delete the repeated elements in place, make each element appear only once, and return the new length of the deleted array.
  • Do not use additional array space. You must modify the input array in place and complete it with O(1) additional space.
  • explain:
    • Why is the returned value an integer, but the output answer is an array?
    • Note that the input array is passed by reference, which means that modifying the input array in the function is visible to the caller.
    • You can imagine the internal operation as follows:
// nums is passed by reference. That is, no copy of the arguments is made
int len = removeDuplicates(nums);

// Modifying the input array in the function is visible to the caller.
// According to the length returned by your function, it will print out all elements within that length range in the array.
for (int i = 0; i < len; i++) {
    print(nums[i]);
}
  • Example 1:
Input: nums = [1,1,2]
Output: 2, nums = [1,2]
Explanation: the function should return a new length of 2 and the original array nums The first two elements of are modified to 1, 2 . There is no need to consider the elements in the array that exceed the new length.
  • Example 2:
Input: nums = [0,0,1,1,1,2,2,3,3,4]
Output: 5, nums = [0,1,2,3,4]
Explanation: the function should return a new length of 5 and the original array nums The first five elements of are modified to 0, 1, 2, 3, 4 . There is no need to consider the elements in the array that exceed the new length.
  • Tips:
    • 0 <= nums.length <= 3 * 104;
    • -104 <= nums[i] <= 104;
    • nums is arranged in ascending order.

2, Solving algorithm

① Double pointer

  • First, note that the array is ordered, so the repeated elements must be adjacent.
  • To remove duplicate elements is actually to move non duplicate elements to the left of the array.
  • Consider using two pointers, one marked as p before and the other marked as q after. The algorithm flow is as follows. Compare whether the elements at positions p and q are equal:
    • If equal, q moves back 1 bit;
    • If it is not equal, copy the element at position q to position p+1, move p one bit later and q one bit later;
  • Repeat the above process until q equals the length of the array, and return p + 1, which is the length of the new array.

  • Java example:
 public int removeDuplicates(int[] nums) {
    if(nums == null || nums.length == 0) return 0;
    int p = 0;
    int q = 1;
    while(q < nums.length){
        if(nums[p] != nums[q]){
            nums[p + 1] = nums[q];
            p++;
        }
        q++;
    }
    return p + 1;
}
  • Continue to optimize and consider the following array:

  • At this time, there are no duplicate elements in the array. According to the above method, Num [P] is not equal to num [q] during each comparison, so the element pointed to by Q will be copied in place. This operation is actually unnecessary. Therefore, you can add a small judgment and copy only when Q - P > 1.
  • Java example:
public int removeDuplicates(int[] nums) {
    if(nums == null || nums.length == 0) return 0;
    int p = 0;
    int q = 1;
    while(q < nums.length){
        if(nums[p] != nums[q]){
            if(q - p > 1){
                nums[p + 1] = nums[q];
            }
            p++;
        }
        q++;
    }
    return p + 1;
}

② Double pointer (LeetCode official solution)

  • Delete the duplicate elements of the given ordered array num. after deleting the duplicate elements, each element only appears once and returns a new length. The above operations must be completed by modifying the array in place and using the spatial complexity of O(1).
  • Since the given array num is ordered, for any I < j, if num [i] = num [j], then for any I ≤ K ≤ j, there must be num [i] = num [k] = num [j], that is, the subscripts of equal elements in the array must be continuous. Using the characteristics of array order, duplicate elements can be deleted by double pointer method.
  • If the length of array nums is 0, the array does not contain any elements, so 0 is returned.
  • When the length of the array num is greater than 0, the array contains at least one element, and at least one element remains after deleting the duplicate element. Therefore, Num [0] can be left as it is, and the duplicate element can be deleted from the subscript 1.
  • Two pointers fast and slow are defined as fast pointer and slow pointer respectively. The fast pointer represents the subscript position reached by traversing the array, and the slow pointer represents the subscript position to be filled in by the next different element. Initially, both pointers point to subscript 1.
  • Assuming that the length of the array num is n, the fast pointer fast will traverse each position from 1 to n − 1 in turn. For each position, if num [fast] ≠ num [fast − 1], it means that num [fast] is different from the previous elements. Therefore, copy the value of num [fast] to num [slow], and then add 1 to the value of slow, that is, point to the next position.
  • After traversal, each element from num [0] to num [slow − 1] is different and contains each different element in the original array. Therefore, the new length is slow, and slow can be returned.
  • Java example:
class Solution {
    public int removeDuplicates(int[] nums) {
        int n = nums.length;
        if (n == 0) {
            return 0;
        }
        int fast = 1, slow = 1;
        while (fast < n) {
            if (nums[fast] != nums[fast - 1]) {
                nums[slow] = nums[fast];
                ++slow;
            }
            ++fast;
        }
        return slow;
    }
}

Topics: Algorithm data structure leetcode Double Pointer