leetcode 283 Move Zeros; 27 Remove Elements; 26 Remove Duplicated from Sorted Array;

 

int arr[] = {0,1,0,3,12};
//把数组的值赋给vector
vector<int> vec(arr, arr+sizeof(arr)/sizeof(int));

解法一:

时间复杂度O(n)

空间复杂度O(1)

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int k = 0;   //nums中,[0,...k)的元素均为非0元素
        //遍历到第i个元素后,保证[0,...i)中所有非0元素
        //都按照顺序排列在[0,...k)中
        for(int i=0;i<nums.size();i++){
            if(nums[i]){
                nums[k++] = nums[i];
            }
        }
        //将nums剩余的位置放置为0
        for(int i=k;i<nums.size();i++)
            nums[i] = 0;
    }
};

解法二:将非0元素与0元素交换位置,其中k指向非零元素的位置,且为了不让两个0元素之间相互交换位置,则增加一个判断条件( i != k)

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int k = 0;   //nums中,[0,...k)的元素均为非0元素
        //遍历到第i个元素后,保证[0,...i)中所有非0元素
        //都按照顺序排列在[0,...k)中
        //同时,[k,...i]为0
        for(int i=0;i<nums.size();i++){
            if(nums[i]){
                if(i!=k)
                    swap(nums[k++] , nums[i]);
                else
                    k++;
            }
        }
    }
};

 

我用了一个比较简便的解法,使用了vector的erase()函数直接删除等于val的元素(相当于下标自动加了一,即表示的是删除元素的下一个元素),剩余的元素个数可以直接由size()得到。

需注意的:不能使用remove()的原因是:它是将等于val的元素放到vector的尾部,返回新的end()值(非val部分的end),但并不减少vector的size

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k = 0; 
        int i = 0;
        while(i<nums.size()){
            if(nums[i] == val)
                nums.erase(nums.begin()+i);    //删除下标为i的元素
            else 
                i++;
        }
        return nums.size();
    }
};

所以要考虑上述三个问题。

 

 

 

 解法一:(16s)

注意:判断当数组的长度为0时返回0,否则容易出现野指针报错。

思路:若找到一个不重复的元素就将它赋给下标为(k+1)的元素,由于k记录的是当前不重复元素的位置。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int k=0;  //记录不重复元素的位置
        int i = k+1;
        if(nums.empty()) return 0;
        while(i<nums.size()){
            if(nums[i]!=nums[k]){
                k++;
                nums[k] = nums[i];
            }
            else
            {
                i++;
            }
        }
        return k+1;    //返回的是数组长度所以下标+1
    }
};

解法二:(24s)

和解法二的思路相似,执行时间较多,比较相邻两个元素是否相同,若相同则i++;若不相同则将nums[i]赋给nums[k]。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if (nums.empty()) return 0;
        int k = 1;
        for (int i = 1; i < nums.size(); ++i)
        {
            if (nums[i] != nums[i - 1])
            {
                 nums[k++] = nums[i];   k++的作用是最终的k是数组的长度
            }
        }
        return k;
    }
};

 

 

 思路:k记录最多重复两次的数组下标,若( 下标为i的元素不等于k) 或者(i等于k 但是 k和k-1不相等)  则把下标为i的元素赋给k+1的元素

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size()<=2) return nums.size();
        int k=1;   //k记录最多重复两次的数组下标
        for(int i=2;i<nums.size();i++){
            if(nums[i]!=nums[k] || (nums[i]==nums[k] && nums[k]!=nums[k-1]) )
                nums[++k] = nums[i];
        }
        return k+1;
    }
};

 

转载于:https://www.cnblogs.com/Bella2017/p/10088753.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值