在C++中删除数组中的重复项

wixjitnu  于 2024-01-09  发布在  其他
关注(0)|答案(4)|浏览(139)

从排序数组中删除重复项

给定一个已排序的数组,删除重复的元素,使每个元素只出现一次,并返回新的长度。
请注意,即使我们希望您返回新的长度,也要确保在适当的位置更改原始数组
不要为另一个数组分配额外的空间,你必须在有常量内存的地方这样做。
我试着遵循代码,我错在哪里?

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int removeDuplicates(vector<int> &A) {
  5. int m=A.size();
  6. if(m<=1) return m;
  7. vector<int> :: iterator i=A.begin();
  8. vector<int> :: iterator j=A.begin()+1;
  9. vector<int> :: iterator temp;
  10. while(i!=A.end() && j!=A.end())
  11. {
  12. while(j!=A.end() && *i == *j)
  13. {
  14. temp=j;
  15. j++;
  16. A.erase(temp);
  17. }
  18. i=j;
  19. j++;
  20. }
  21. return A.size();
  22. }
  23. int main()
  24. {
  25. vector<int> vec={0,0,0,0,0,0,0,4,4,7,7,7,7,9};
  26. cout<<"ans="<<removeDuplicates(vec);
  27. return 0;
  28. }

字符串

huwehgph

huwehgph1#

当你递增j,然后erase这个元素,从j+1开始的元素向下移动,你通过递增跳过了一个元素。
一个更好的方法是简单地将非重复元素从一个迭代器复制到另一个迭代器,并在主循环结束时设置新的长度。您当前的方法可能是O(n^2),对于实际使用来说太慢了。

mzaanser

mzaanser2#

我认为这是你需要的。这个函数从尾部到头部循环数组,并计算相同的值。然后在不唯一的值上执行已经唯一的值的移位。它不会改变向量的实际大小,因为它可能会涉及向量内部内存的重新分配。

  1. int removeDuplicates(vector<int> &vec) {
  2. int currentVal = vec.size() - 1;
  3. int uniqueNumber = 0;
  4. while (currentVal >= 0) {
  5. ++uniqueNumber;
  6. int sameVal = currentVal;
  7. while (sameVal > 0 && vec[sameVal - 1] == vec[currentVal])
  8. --sameVal;
  9. int shiftSize = uniqueNumber;
  10. for (int k = 1; k < shiftSize; ++k) {
  11. vec[sameVal + k] = vec[currentVal + k];
  12. }
  13. currentVal = sameVal - 1;
  14. }
  15. return uniqueNumber;
  16. }

字符串

展开查看全部
3hvapo4f

3hvapo4f3#

你被要求使用一个数组。尽管vector在很多方面都很相似,但它是不一样的。看看下面的示例代码。
此外,你被要求保持分配的内存相同。你不能确保使用vector,一旦你添加/删除元素,它的大小可以增长/收缩,当一个元素被删除时,vector后面的数组中的数据将被重新分配和重写。

  1. int main()
  2. {
  3. int arr[14] = {0,0,0,0,0,4,4,4,4,5,5,5,7,9};
  4. int last_non_duplicate_index = 0;
  5. int current_index = 0;
  6. int size = 14;
  7. int new_size = size;
  8. bool is_last_value = false;
  9. // you can use for interchangeably
  10. while(!is_last_value)
  11. {
  12. current_index++; // move one position ahead
  13. if(current_index < size) // out of bonds check
  14. {
  15. if(arr[last_non_duplicate_index] != arr[current_index]) // value at position of current index is different
  16. {
  17. last_non_duplicate_index++; // increase index of the last value which was not a duplicate by one
  18. arr[last_non_duplicate_index] = arr[current_index]; // write at that index
  19. // e.g. if last index was 0 -> increase it to 1 and rewrite whatsever under arr[1] (current index)
  20. }
  21. else // values are the same
  22. {
  23. new_size--; // devrease the size
  24. }
  25. }
  26. else
  27. {
  28. is_last_value = true; // current_index >= size -> out of bonds
  29. }
  30. }
  31. for (int i = 0; i < new_size; i++)
  32. {
  33. std::cout << "arr[" << i << "]" << " = " << arr[i] << std::endl;
  34. }
  35. std::cout << "New size: " << new_size << std::endl;
  36. return 0;
  37. }

字符串

展开查看全部
slmsl1lt

slmsl1lt4#

你可以这样使用迭代器:

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int removeDuplicates(vector<int> &A) {
  5. int m = A.size();
  6. if(m <= 1) return m;
  7. for (auto it1 = A.begin(); it1 != A.end(); it1++) {
  8. for (auto it2 = it1 + 1; it2 != A.end();) {
  9. if (*it1 == *it2) {
  10. it2 = A.erase(it2);
  11. } else {
  12. it2++;
  13. }
  14. }
  15. }
  16. return A.size();
  17. }
  18. int main()
  19. {
  20. vector<int> vec = { 0, 0, 0, 0, 0, 0, 0, 4, 4, 7, 7, 7, 7, 9 };
  21. cout << "ans=" << removeDuplicates(vec);
  22. return 0;
  23. }

字符串

展开查看全部

相关问题