算法与数据结构之数组专题

一.移除数组元素

26. Remove Duplicates from Sorted Array

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
For example,
Given input array nums = [1,1,2],
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.

意思是说要得到新数组并且返回长度,但是新数组并不需要删除元素,所以,贴上代码

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size()<2)
            return nums.size();
      int id = 1;
        for(int i = 1; i < nums.size(); ++i) 
            if(nums[i] != nums[i-1]) 
                nums[id++] = nums[i];
        return id;

    }
};

还有另外一种思路,如果得到一个新数组并且只要在循环中判断前一个新数组元素成员是否等于接下来的数组元素即可

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int length = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (i == 0 || nums[i] != nums[length-1]) {
                nums[length] = nums[i]; 
                length++; 
            }
        }
        return length;        
    }
};

27. 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.

异曲同工之妙,想了一下就出来AC了

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int id=0;
        for(int i = 0;i<nums.size();i++)
        {
            if(nums[i]!=val)
                nums[id++]=nums[i];
        }
        return id;
    }
};

二.找寻重复元素

645. Set Mismatch

The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number.
Given an array nums representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array.
Example 1:
Input: nums = [1,2,2,4]
Output: [2,3]

常规思路

先排序,再依次找出对应元素,时间较慢。

class Solution {
public:
    vector<int> findErrorNums(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int ans;
        int res = 0;
        for(int i = 1;i<nums.size();i++)
        {
            if(nums[i]==nums[i-1])
            {
                ans = i-1;
                nums.erase(nums.begin()+i);
                i = i - 1;
                continue;
            }
            else if(nums[i] != nums[i-1]+1)
                res = i;
        }
        vector<int>result(2);
        result[0] = nums[ans];
        if(res == 0 )
        {
            if(nums[0] != 1)
                result[1] = 1;
            else
                result[1] = nums[nums.size()-1]+1;
        }
        else
            result[1] = nums[res]-1;
        return result;
    }
};

优化思路

这次不用排序了,直接上,并且利用temp临时数组存储,找寻为0的元素

class Solution {
public:
    vector<int> findErrorNums(vector<int>& nums) {
        int len = nums.size();
        vector<int>temp(len,0);
        vector<int>res(2,0);
        for(int i = 0;i<len;i++)
        {
            temp[nums[i]-1] += 1;
            if(temp[nums[i]-1] == 2)
                res[0] = nums[i];
        }
        for(int i = 0;i<len;i++)
        {
            if(temp[i]==0)
                res[1] = i+1;
        }
        return res;
    }
};

三.将两排序数组合并为一个排序数组

88. Merge Sorted Array

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note:
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.

常规思路

常规思路是先合并,后用希尔排序

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int sum = m+n;
        for(int i = m;i<sum;i++)
        {
            nums1[i]=nums2[i-m];
        }
        int h = 1;
        while(h<sum/3)
            h = 3*h+1;
        while(h>=1)
        {
            for(int i = h;i<sum;i++)
            {
                for(int j = i;j>=h &&nums1[j]<nums1[j-h];j-=h )
                    swap(nums1[j],nums1[j-h]);
            }
            h/=3;
        }
}
};

因为数组基本有序,故希尔排序效率高

简化算法

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) 
    {
        int i = m-1,j=n-1,sum=m+n-1;
        while(j>=0)
            nums1[sum--]=  i>=0 && nums1[i]>nums2[j]?nums1[i--]:nums2[j--];
    }
};

虽然简便但是效率低

posted @ 2017-07-30 14:28  vhyz  阅读(285)  评论(0编辑  收藏  举报