当前位置:   article > 正文

删除有序数组中的重复项(C Language)

删除有序数组中的重复项

题目

26. 删除有序数组中的重复项 - 力扣(Leetcode)https://leetcode.cn/problems/remove-duplicates-from-sorted-array/

思路1:暴力求解

这个题目暴力的解法就是找到重复项,多次挪动数据覆盖删除。通过两层循环,外层循环遍历数组元素,内层循环更新数组。

很明显暴力解法的时间复杂度是O(N^{2}),这道题目暴力解法在LeetCode上是可以过的。 

  1. int removeDuplicates(int* nums, int numsSize)
  2. {
  3. if (numsSize == 0)
  4. {
  5. return 0;
  6. }
  7. int i = 0;
  8. while (i < numsSize - 1)
  9. {
  10. if (nums[i] == nums[i + 1])
  11. {
  12. for (int j = i + 1; j < numsSize - 1; ++j)
  13. {
  14. nums[j] = nums[j + 1];
  15. }
  16. --numsSize;
  17. }
  18. else
  19. {
  20. ++i;
  21. }
  22. }
  23. return i + 1;
  24. }

思路2:开辟额外的数组

开辟一个临时数组,依次遍历nums数组,把相同的值合成一个数tmp数组中,再把tmp的值拷贝回去。此时时间复杂度为O(N),但是空间复杂度也为O(N),经典的空间换时间。

但是该解法不满足题目空间复杂度为O(1)的条件。

  1. int removeDuplicates(int* nums, int numsSize)
  2. {
  3. if (numsSize == 0)
  4. {
  5. return 0;
  6. }
  7. int* tmp = (int*)malloc(sizeof(int) * numsSize);
  8. tmp[0] = nums[0];
  9. int size = 1;
  10. for (int i = 1; i < numsSize; ++i)
  11. {
  12. if (nums[i] != tmp[size - 1])
  13. {
  14. tmp[size] = nums[i];
  15. ++size;
  16. }
  17. }
  18. for (int j = 0; j < size; ++j)
  19. {
  20. nums[j] = tmp[j];
  21. }
  22. free(tmp);
  23. tmp = NULL;
  24. return size;
  25. }

思路3:双指针

首先注意数组是有序的,那么重复的元素一定会相邻。其次题目要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。

考虑用2个指针,一个在前记作left,一个在后记作right,比较left和right位置的元素是否相等。

如果相等,right后移1位;如果不相等,将right位置的元素复制到left+1位置上,left后移1位,right后移1位。

重复上述过程,直到right等于数组长度。

返回left+1,即为新数组长度。

  1. int removeDuplicates(int* nums, int numsSize)
  2. {
  3. if (numsSize == 0)
  4. {
  5. return 0;
  6. }
  7. int left = 0;
  8. int right = 1;
  9. while (right < numsSize)
  10. {
  11. if (nums[right] != nums[left])
  12. {
  13. nums[left + 1] = nums[right];
  14. left++;
  15. right++;
  16. }
  17. else
  18. {
  19. right++;
  20. }
  21. }
  22. return left + 1;
  23. }

思路4:三指针

三指针是在双指针的基础上改进的,便于理解。

设立三个指针,一个指针dst指向下一个将要赋值的位置,另外两个指针left、right指向重复项的区间范围。

  1. int removeDuplicates(int* nums, int numsSize)
  2. {
  3. if (numsSize == 0)
  4. {
  5. return 0;
  6. }
  7. int dst = 0;
  8. int left = 0;
  9. int right = 1;
  10. while (right < numsSize)
  11. {
  12. if (nums[right] == nums[left])
  13. {
  14. ++right;
  15. }
  16. else
  17. {
  18. nums[dst] = nums[left];
  19. ++dst;
  20. left = right;
  21. ++right;
  22. }
  23. }
  24. nums[dst] = nums[left];
  25. ++dst;
  26. return dst;
  27. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/434395
推荐阅读
相关标签
  

闽ICP备14008679号