LeetCode 27. Remove Element

题目链接:https://leetcode.com/problems/remove-element/

题目描述:

Given an array and a value, remove all instances of that value in place and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Example:
Given input array nums = [3,2,2,3]val = 3

Your function should return length = 2, with the first two elements of nums being 2.

Hint:

  1. Try two pointers.
  2. Did you use the property of "the order of elements can be changed"?
  3. What happens when the elements to remove are rare?

思路1:一开始的思路是用erase函数,直接删除,注意这里,删除目标元素后,指针不用后移,因为vector是顺序存储,删除当前元素后,后面的元素会向前移动,指针自然指向后面的元素。

代码:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        vector<int>::iterator iter=nums.begin();
        while(iters!=nums.end())
        {
            if(*iter==val)
            {
                nums.erase(iter);
            }
            else
                iter++;
        }
        return nums.size();
    }
};

思路2:每次遇到目标元素,就把末尾元素复制到当前位置,pop_back()出末尾元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        vector<int>::iterator i=nums.begin(),tmp;
        while(i!=nums.end())
        {
            if(*i==val)
            {
                *i=nums[nums.size()-1];
                nums.pop_back();
            }
            else
                i++;
        }
        return nums.size();
    }
};
思路3:借鉴网上的,用双指针,这里关键是返回长度即可,遇到与目标元素不相等的就放到前面。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int i = 0 , k = 0;
        while (i < nums.size())
        {
            if (nums[i] != val)
                nums[k++] = nums[i];
            i++;
        }
        return k;
    }
};
注意:这里返回k即可,nums现在存的是什么不管
收集了一点干货:
Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。
由于Iterator模式的以上特性:与聚合对象耦合,在一定程度上限制了它的广泛运用,一般仅用于底层聚合支持类,如STL的list、vector、stack等容器类及ostream_iterator等扩展iterator。
根据STL中的分类,iterator包括:
Input Iterator:只能单步向前迭代元素,不允许修改由该类迭代器引用的元素。
Output Iterator:该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。
Forward Iterator:该类迭代器可以在一个正确的区间中进行读写操作,它拥有Input Iterator的所有特性,和Output Iterator的部分特性,以及单步向前迭代元素的能力。
Bidirectional Iterator:该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。
Random Access Iterator:该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。


vector 和deque提供的是RandomAccessIterator,list提供的是BidirectionalIterator,set和map提供的 iterators是 ForwardIterator




vector中的元素在内存中确实是连续存储的. vector的实现是由一个动态数组构成. 当空间不够的时候, 采用类似于C语言的realloc函数重新分配空间. 正是因为vector中的元素是连续存储的, 所以vector支持常数时间内完成元素的随机访问. vector中的iterator属于Random Access Iterator.


如果vector储存的是string类型. 情况也是一样的. 值得注意的是, string类型并不是简单的char 数组. string中的数组其实也是动态分配的. 为了方便, 你可以这样理解(不完全正确), 当vector中存储string类型时, 其实是数组中存着许多char *类型的指针, 每个指针指向的内容才是string的字符内容. 可以给你一个简单的图示
                 +----+----+----+----+----+----+
    vector    |    *   |   *   |  *    |  *    |       |        |
                 +-- |-+--|---- |---- |-------------+
                       |       |       |       |
                      v      v      v      v
                     s1    s2    s3    s4        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值