- Leetcode-26Remove Duplicates fro
- LeetCode 26. Remove Duplicates f
- ZXAlgorithm - Leetcode Top Inter
- Remove Duplicates from Sorted Ar
- 26 Remove Duplicates From Sorted
- 83 Remove Duplicates From Sorted
- Remove Duplicates from Sorted Ar
- Remove Duplicates from Sorted Ar
- Remove Duplicates from Sorted Ar
- Remove Duplicates from Sorted Ar
每日算法——letcode系列
问题 Remove Duplicates from Sorted Array II
Difficulty:<strong>Medium</strong></br>
<p><p>
Follow up for "Remove Duplicates":<br />
What if duplicates are allowed at most <i>twice</i>?</p>
<p>
For example,<br />
Given sorted array <i>nums</i> = <code>[1,1,1,2,2,3]</code>,</p>
<p>
Your function should return length = <code>5</code>, with the first five elements of <i>nums</i> being <code>1</code>, <code>1</code>, <code>2</code>, <code>2</code> and <code>3</code>. It doesn't matter what you leave beyond the new length.
</p></p>
// C++
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
}
};
翻译 移除有序数组中重复元素II
难度系数:<strong>中等</strong></br>
接着上一个总是“删除重复数”:<br />
如果可以重复的数最多只允许 <i>两</i>次呢?</p>
例如,<br />
给定一个有序的数组 <i>nums</i> = <code>[1,1,1,2,2,3]</code>,
函数返回的长度应 = <code>5</code>,数组<i>nums</i>的前五个元素应为 <code>1</code>, <code>1</code>, <code>2</code>, <code>2</code> 和<code>3</code>
思路
由于是有序的,上题是相邻不能相等,现在相当于是隔一个不能相等,本质上一样, 可以和上一题写一个通用的代码
// C++
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = static_cast<int>(nums.size());
if (n < 3){
return n;
}
int index = 2;
for (int i = 2; i < n; ++i){
if (nums[index - 2] != nums[i]){
nums[index++] = nums[i];
}
}
for (int i = 0; i < n - index; ++i){
nums.pop_back();
}
return index;
}
};
// 通用
class Solution {
public:
/**
* remove duplicates if the number of duplicates more than num
*
* @param nums <#nums description#>
* @param num <#num description#>
*
* @return size of new nums
*/
int removeDuplicates(vector<int>& nums, int num) {
int n = static_cast<int>(nums.size());
if (n < num + 1){
return n;
}
int index = num;
for (int i = 2; i < n; ++i){
if (nums[index - num] != nums[i]){
nums[index++] = nums[i];
}
}
for (int i = 0; i < n - index; ++i){
nums.pop_back();
}
return index;
}
};
前文延伸解决
注:前文中文版个人觉得翻译有问题,不应该是有序的,应该是一系列整数, 有序的就太简单了
分析
由于4 300 000 000大于$2{32}$,且1到$2{32}$中每个数都至少有一个,所以必须有重复的数,题目设置成这么大的数,主要是不要考虑全部读取到内存的方案,为方便测试可以用1到256的取258个数(258 >$2^8$)来测试。
方案一:
用一个char类型的数据,由于一个char占8个字节,每个字节两个比特位,一共有256个比特位,读取一个数,如果这个数是2,先判断char类型数据的第二个比特位上是否为0,如果为0就把设置为1,如果为1代表这个数出现, 时间复杂度$T_{n} = O{(n)} $, 其实本质上就是hashmap的方案,只不过更省空间。
方案二:
二分法(注:《编程珠玑》推荐的方案)
读到一个数,最高比特位如果是0,放在A堆,最高比特位如果是1放到B堆,这样就把258,人为的分成了两堆,现在如果哪堆的个数大于$256/2=128$, 证明重复的数在哪堆,也有可能两堆都有, 再读最高位的下一位比特位再分堆,如此反复肯定能找到那个重复的数
延伸思考
如果是$2^{32}$ + 1个数呢?也就是只有一个重复的数,怎么来找此数呢?有没有更低的时间复杂度方案?
网友评论