题目:
$O(nk)$
先排个序,然后贪心地选择每次能取到的最小的,$ 0 < offset <= 2 \times k$这种情况下选择用循环取找下一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include <vector> #include <algorithm>
using std::vector;
class Solution { public: int maxDistinctElements(vector<int> &nums, int k) { int i, j; int n = nums.size(); int res = 1; int last_val; int offset;
std::sort(nums.begin(), nums.end());
last_val = nums[i] - k;
for (i = 1; i < n; i++) { offset = nums[i] - nums[i - 1]; if (offset == 0 && last_val != nums[i - 1] + k) { last_val = last_val + 1; res++;
} else if (offset > 2 * k) { last_val = nums[i] - k; res++;
} else {
for (j = 0; j < 2 * k + 1; j++) { if (nums[i] - k + j > last_val) { res++; last_val = nums[i] - k + j; break; } } } }
return res; } }; int main() { Solution s; vector<int> vec = { 1, 2, 2, 3, 3, 4 }; s.maxDistinctElements(vec, 2); }
|
$O(n)$
只需要遍历一遍,主要思想是优化$ 0 < offset <= 2 \times k$的情况,下一个值取到哪里与 nums[i] - k 和 last_val 有关,对其情况进行穷举避免循环遍历。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include <vector> #include <algorithm>
using std::vector;
class Solution { public: int maxDistinctElements(vector<int> &nums, int k) { int i, j; int n = nums.size(); int res = 1; int last_val; int offset;
std::sort(nums.begin(), nums.end());
last_val = nums[i] - k;
for (i = 1; i < n; i++) { offset = nums[i] - nums[i - 1]; if (offset == 0 && last_val != nums[i - 1] + k) { last_val = last_val + 1; res++; } else if (offset == 0 && last_val == nums[i - 1] + k) { continue; } else if (offset > 2 * k) { last_val = nums[i] - k; res++;
} else { if (nums[i] - k > last_val) { last_val = nums[i] - k; res++;
} else { last_val = last_val + 1; res++; } } }
return res; } }; int main() { Solution s; vector<int> vec = { 1, 2, 2, 3, 3, 4 }; s.maxDistinctElements(vec, 2); }
|