26/80. Remove Duplicates from Sorted Array I/II(C++)

注:此博客不再更新,所有最新文章将发表在个人独立博客limengting.site。分享技术,记录生活,欢迎大家关注

6点清晨的阳光真好。
开始成长的第一天,开始刷leetcode,新建了博客开始记录自己的成长。写下一些不懂的知识点慢慢进步,希望能真正感受到算法之美,也希望自己在本科毕业的时候能够如愿找到好工作。

vector和string优先于动态分配的数组:
(1)用new声明多维动态数组:
先声明一个n维数组,每个单元是指向int的指针,再分别对每个单元分配内存.代码如下:

int** ary = new int* [row_num];
for(int i = 0; i < row_num; ++i)
	ary[i] = new int[col_num];

注意:上面代码在释放分配的内存时要特别注意。因为这是“深度内存分配”,所以释放时,要对每个单元里的指针指向的内存予以释放。释放内存代码如下:

for(i = 0; i < row_num; ++i)
	delete[] ary[i];
delete[] ary;

(2)用vector(优先):

vector<vector<int>> array(row_num, vector<int>(col_num, 0));

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.

代码1:时间复杂度O(n),空间复杂的O(1)

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

代码2:时间复杂度O(n),空间复杂的O(1)
unique函数:去重函数, unique的功能是去除相邻的重复元素(只保留一个),其实它并不真正把重复的元素删除,是把重复的元素移到后面去了,然后依然保存到了原数组中,然后 返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。
distance函数:求出两个iterator之间的距离

// 使用STL
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
       return distance(nums.begin(), unique(nums.begin(), nums.end()));
    }
};

代码3:(??未懂,多刷题了再来看吧)

// 使用STL
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
       return distance(nums.begin(), removeDuplicates(nums.begin(), nums.end(), nums.begin()));
    }
    
    template<typename InIt, typename OutIt>
    OutIt removeDuplicates(InIt first, InIt last, OutIt output) {
        while (first != last) {
            *output++ = *first;
            first = upper_bound(first, last, *first);
        }
        
        return output;
    }
};

补充upper_bound函数源码:

int upper_bound(int* array, int size, int key) {
	int len = size-1;
	int half, middle;
 
	while(len > 0) {
		half = len >> 1;
		middle = first + half;
		if(array[middle] > key)     //中位数大于key,在包含last的左半边序列中查找。
			len = half;
		else {
			first = middle + 1;    //中位数小于等于key,在右半边序列中查找。
			len = len - half - 1;
		}
	}
	return first;
}

补充lower_bound函数源码:

//这个算法中,first是最终要返回的位置
int lower_bound(int *array, int size, int key) {
	int first = 0, middle;
	int half, len;
	len = size;
 
	while(len > 0) {
		half = len >> 1;
		middle = first + half;
		if(array[middle] < key) {    
			first = middle + 1;         
			len = len-half-1;       //在右边子序列中查找
		}
		else
			len = half;            //在左边子序列(包含middle)中查找
	}
	return first;
}
  1. Remove Duplicates from Sorted Array II

Follow up for “Remove Duplicates”:
What if duplicates are allowed at most twice?

For example,
Given sorted array nums = [1,1,1,2,2,3],

Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn’t matter what you leave beyond the new length.

代码1:

//扩展性更好,只要将 < 2 都改为 < 3 则变成求最多重复3次
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if (nums.size() <= 2) return nums.size();
        
        int index = 2;
        for (int i = 2; i < nums.size(); i++) {
            if (nums[i] != nums[index - 2]) // 用右边的值向左平移,把多于两个重复的值覆盖掉
                nums[index++] = nums[i]; // 如果当前值与前面的第二个值相同则此次index不自增
        }
        return index;
    }
};

代码2:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
       const int n = nums.size();
       int index = 0;
       for (int i = 0; i < n; ++i) {
            if (i > 0 && i < n - 1 && nums[i] == nums[i-1] && nums[i] == nums[i + 1])
            continue;// 如果当前值与左边的值右边的值都相同则退出此次循环,此次index不自增
            
            nums[index++] = nums[i];
       }
       return index;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值