Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.3397
Browse files Browse the repository at this point in the history
No.3397.Maximum Number of Distinct Elements After Operations
  • Loading branch information
yanglbme committed Dec 22, 2024
1 parent 1f07b03 commit f7b5a13
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,32 +66,108 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3397.Ma

<!-- solution:start -->

### 方法一
### 方法一:贪心 + 排序

我们不妨对数组 $\textit{nums}$ 排序,然后从左到右考虑每个元素 $x$。

对于第一个元素,我们可以贪心地将其变为 $x - k$,这样可以使得 $x$ 尽可能小,给后续的元素留下更多的空间。我们用变量 $\textit{pre}$ 当前使用到的元素的最大值,初始化为负无穷大。

对于后续的元素 $x$,我们可以贪心地将其变为 $\min(x + k, \max(x - k, \textit{pre} + 1))$。这里的 $\max(x - k, \textit{pre} + 1)$ 表示我们尽可能地将 $x$ 变得更小,但不能小于 $\textit{pre} + 1$,如果存在该值,且小于 $x + k$,我们就可以将 $x$ 变为该值,不重复元素数加一,然后我们更新 $\textit{pre}$ 为该值。

遍历结束,我们就得到了不重复元素的最大数量。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def maxDistinctElements(self, nums: List[int], k: int) -> int:
nums.sort()
ans = 0
pre = -inf
for x in nums:
cur = min(x + k, max(x - k, pre + 1))
if cur > pre:
ans += 1
pre = cur
return ans
```

#### Java

```java

class Solution {
public int maxDistinctElements(int[] nums, int k) {
Arrays.sort(nums);
int n = nums.length;
int ans = 0, pre = Integer.MIN_VALUE;
for (int x : nums) {
int cur = Math.min(x + k, Math.max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
}
```

#### C++

```cpp

class Solution {
public:
int maxDistinctElements(vector<int>& nums, int k) {
ranges::sort(nums);
int ans = 0, pre = INT_MIN;
for (int x : nums) {
int cur = min(x + k, max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
};
```
#### Go
```go
func maxDistinctElements(nums []int, k int) (ans int) {
sort.Ints(nums)
pre := math.MinInt32
for _, x := range nums {
cur := min(x+k, max(x-k, pre+1))
if cur > pre {
ans++
pre = cur
}
}
return
}
```

#### TypeScript

```ts
function maxDistinctElements(nums: number[], k: number): number {
nums.sort((a, b) => a - b);
let [ans, pre] = [0, -Infinity];
for (const x of nums) {
const cur = Math.min(x + k, Math.max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,32 +64,108 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3397.Ma

<!-- solution:start -->

### Solution 1
### Solution 1: Greedy + Sorting

We can sort the array $\textit{nums}$ and then consider each element $x$ from left to right.

For the first element, we can greedily change it to $x - k$, making $x$ as small as possible to leave more space for subsequent elements. We use the variable $\textit{pre}$ to track the maximum value of the elements used so far, initialized to negative infinity.

For subsequent elements $x$, we can greedily change it to $\min(x + k, \max(x - k, \textit{pre} + 1))$. Here, $\max(x - k, \textit{pre} + 1)$ means we try to make $x$ as small as possible but not smaller than $\textit{pre} + 1$. If this value exists and is less than $x + k$, we can change $x$ to this value, increment the count of distinct elements, and update $\textit{pre}$ to this value.

After traversing the array, we obtain the maximum number of distinct elements.

The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the length of the array $\textit{nums}$.

<!-- tabs:start -->

#### Python3

```python

class Solution:
def maxDistinctElements(self, nums: List[int], k: int) -> int:
nums.sort()
ans = 0
pre = -inf
for x in nums:
cur = min(x + k, max(x - k, pre + 1))
if cur > pre:
ans += 1
pre = cur
return ans
```

#### Java

```java

class Solution {
public int maxDistinctElements(int[] nums, int k) {
Arrays.sort(nums);
int n = nums.length;
int ans = 0, pre = Integer.MIN_VALUE;
for (int x : nums) {
int cur = Math.min(x + k, Math.max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
}
```

#### C++

```cpp

class Solution {
public:
int maxDistinctElements(vector<int>& nums, int k) {
ranges::sort(nums);
int ans = 0, pre = INT_MIN;
for (int x : nums) {
int cur = min(x + k, max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
};
```
#### Go
```go
func maxDistinctElements(nums []int, k int) (ans int) {
sort.Ints(nums)
pre := math.MinInt32
for _, x := range nums {
cur := min(x+k, max(x-k, pre+1))
if cur > pre {
ans++
pre = cur
}
}
return
}
```

#### TypeScript

```ts
function maxDistinctElements(nums: number[], k: number): number {
nums.sort((a, b) => a - b);
let [ans, pre] = [0, -Infinity];
for (const x of nums) {
const cur = Math.min(x + k, Math.max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution {
public:
int maxDistinctElements(vector<int>& nums, int k) {
ranges::sort(nums);
int ans = 0, pre = INT_MIN;
for (int x : nums) {
int cur = min(x + k, max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
func maxDistinctElements(nums []int, k int) (ans int) {
sort.Ints(nums)
pre := math.MinInt32
for _, x := range nums {
cur := min(x+k, max(x-k, pre+1))
if cur > pre {
ans++
pre = cur
}
}
return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution {
public int maxDistinctElements(int[] nums, int k) {
Arrays.sort(nums);
int n = nums.length;
int ans = 0, pre = Integer.MIN_VALUE;
for (int x : nums) {
int cur = Math.min(x + k, Math.max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:
def maxDistinctElements(self, nums: List[int], k: int) -> int:
nums.sort()
ans = 0
pre = -inf
for x in nums:
cur = min(x + k, max(x - k, pre + 1))
if cur > pre:
ans += 1
pre = cur
return ans
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function maxDistinctElements(nums: number[], k: number): number {
nums.sort((a, b) => a - b);
let [ans, pre] = [0, -Infinity];
for (const x of nums) {
const cur = Math.min(x + k, Math.max(x - k, pre + 1));
if (cur > pre) {
++ans;
pre = cur;
}
}
return ans;
}

0 comments on commit f7b5a13

Please sign in to comment.