Timeline greedy Problem:
O(nk) First sort, then greedily choose the smallest possible each time. In the case of 0 < o f f s e t < = 2 × k 0 < offset <= 2 \times k 0 < o f f se t <= 2 × k , use a loop to find the next one.
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) Only need to traverse once. The main idea is to optimize the case of 0 < o f f s e t < = 2 × k 0 < offset <= 2 \times k 0 < o f f se t <= 2 × k . Where the next value is taken depends on nums[i] - k and last_val. Enumerate its cases to avoid loop traversal.
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 ); }