Skip to content

feat: add solutions to lc problem: No.3397 #3878

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
Loading