1. 程式人生 > >leetcode 283 Move Zeros; 27 Remove Elements; 26 Remove Duplicated from Sorted Array;

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;
    }
};