美文网首页
2019-01-25 第一天 (#27, #26, #80)

2019-01-25 第一天 (#27, #26, #80)

作者: 被子十三 | 来源:发表于2019-01-31 14:04 被阅读5次

刷题顺序来自于cspiration

#27 Remove Element

题目地址:https://leetcode.com/problems/remove-element/

初见 (O(n^2)复杂度)

初见过度依赖于C++的erase()这个函数,用这个函数把指定值的元素擦除,再在末尾用push_back()补一个0。需要建立两个索引变量,其中一个用来控制循环次数,另外一个用来读取数组元素。
代码如下:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size = nums.size();
        int counter = 0;
        int ind = 0;
        for(auto it = 0; it < size; it++){
            if(nums.at(ind) == val){
                nums.erase(nums.begin()+ind);
                nums.push_back(0);
                counter++;
            }
                
            else
                ind++;
        }
        
        return size-counter;
    }
};

这个代码虽然击败了98.42%的submissions,但是实际上性能怎么样我自己还是心知肚明的。
erase()函数的时间复杂度最坏情况是O(n),考虑到循环次数为n,总的复杂度应该是O(n^2)。

Two Pointers(O(n)复杂度)

提示里有一个“Use two pointers",想了半天也没想出来是咋回事,怒看答案。答案的思路其实和初见版本已经极其接近了,two pointers的意思估计就是两个索引变量。只是对比初见版本的思路是擦除错误元素,这个算法的思路是留下正确元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size = nums.size();
        int counter = 0;
        int ind = 0;
        for(auto it = 0; it < size; it++){
            if(nums.at(it) != val){
                nums.at(counter) = nums.at(it);
                counter++;
            }
        }
        
        return counter;
    }
};

显然覆盖的时间复杂度是O(1)。总体时间复杂度是O(n)。虽然实际执行时间同样是4ms,但是这个算法显然比第一个快得多。

交换(O(n)复杂度)

这个思想和初见其实一模一样(本质上都是交换),但是比起先擦除再插入,为什么不直接交换呢?

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size = nums.size();
        int counter = 0;
        int ind = 0;
        for(auto it = 0; it < size; it++){
            if(nums.at(ind) == val){
                iter_swap(nums.begin()+ind, nums.end()-1);
                nums.erase(nums.end()-1);
                counter++;
            }
                
            else
                ind++;
        }
        
        return size-counter;
    }
};

这次由于erase()只擦除最后一个元素,复杂度为O(1),而iter_swap()复杂度也是O(1),时间复杂度就为O(n)。
这个算法所需时间和前面的Two Pointers应该是一致的,具体谁优谁劣取决于实际上是要擦除的元素多还是要留下的元素多。值得一提的是这个算法击败了100%的submissions。

#26 Remove Duplicates from Sorted Array

初见 (O(n)复杂度)

和#27的Two Pointer思路一毛一样。唯一要注意的就是这个烂鬼test case里还包含数组为空的情况。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        
        int size = nums.size();
        if(size == 0)
            return 0;
        int counter = 1;
        int temp = nums.at(0);
        for(int ind = 1; ind < size; ind++){ // Index starts from 1
            if(nums.at(ind) != temp){
                nums.at(counter) = nums.at(ind);
                temp = nums.at(ind);
                counter++;
                
            }
        }
        
        return counter;
    }
};

#80 Remove Duplicates from Sorted Array II

初见(O(n)复杂度)

这不就是#26的状态机版本嘛,你也配medium?

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int size = nums.size();
        if(size == 0)
            return 0;
        int counter = 1;
        int temp = nums.at(0);
        int state = 1;
        for(int ind = 1; ind < size; ind++){ // Index starts from 1
            if(nums.at(ind) == temp && state == 2){
                // Do nothing
            }
            else if(nums.at(ind) == temp){
                state++;
                nums.at(counter) = nums.at(ind);
                counter++;
            }
            else{
                state = 1;
                nums.at(counter) = nums.at(ind);
                temp = nums.at(ind);
                counter++;
            }
        }
        return counter;
    }
};

相关文章

  • 2019-01-25 第一天 (#27, #26, #80)

    刷题顺序来自于cspiration。 #27 Remove Element 题目地址:https://leetco...

  • 数组 26、27、80

    快慢指针,fast指向当前处理的值slow的值代表:遇到合法的值,将合法的值放在slow的位置。 lc80

  • 2019-01-26

    2019-01-25 桓台姜博士眼镜商迎新 2019-01-26 2019-01-26 桓台姜博士眼镜商迎新 20...

  • 9.15-9.16

    9.15 多云 20°-26° 除草 咱们地成了天然牧场 种植萝卜满堂红约80m² 9.16 晴 20°-27...

  • 2019-01-26

    2019-01-25 每天使用1%的时间,进步1%,成为1%的人! 今天是什么日子:2019年1月26日 日出: ...

  • 2019-01-25

    2019-01-25

  • 80天环游地球:Day 26-27 , 逃离印度,漫长38小时旅

    80天环游地球:Day 26-27 , 逃离印度,漫长38小时旅途 印度菩提伽耶-加尔各答-泰国曼谷-普吉岛 樱...

  • 开学了

    4月26日开学。 26、27日开学考试,28号算正式上课第一天。 晚上放学回家,女儿说,今天数学老师上课一进教室就...

  • 2019-01-25

    2019-01-24 桓台姜博士眼镜商迎新 2019-01-25 2019-01-25 桓台姜博士眼镜商迎新 20...

  • 带着爸妈去旅行(2)——国中之国梵蒂冈

    2018年7月26日,欧洲游第一天,飞机上 2018年7月27日,欧洲游第二天,游玩地:梵蒂冈 2018年7月26...

网友评论

      本文标题:2019-01-25 第一天 (#27, #26, #80)

      本文链接:https://www.haomeiwen.com/subject/bncijqtx.html