Skip to content
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

Added Bucket Sort #651

Closed
wants to merge 1 commit into from
Closed
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
211 changes: 211 additions & 0 deletions solutions/0100-0199/0164-maximum-gap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
---
description: >-
Author: @Sanchita1304 |
https://leetcode.com/problems/maximum-gap/
---

# 0164 - Maximum Gap (Medium)

## Problem Link

https://leetcode.com/problems/maximum-gap/

## Problem Statement

Given an integer array nums, return the maximum difference between two successive elements in its sorted form. If the array contains less than two elements, return 0.

You must write an algorithm that runs in linear time and uses linear extra space.

**Example 1:**

```
Input: nums = [3,6,9,1]
Output: 3

Explanation: The sorted form of the array is [1,3,6,9], either (3,6) or (6,9) has the maximum difference 3.
```

**Example 2:**

```
Input: nums = [10]
Output: 0

Explanation: The array contains less than 2 elements, therefore return 0.
```


**Constraints:**

- `1 <= nums.length <= 105`
- `0 <= nums[i] <= 109`

## Approach 1: Using Bucket Sort with Uniform Bucket Sizes

1. Edge Case Check:

Start by checking if the input array nums has fewer than 2 elements. If so, return 0 since there are not enough elements to calculate a gap.

2. Find Maximum and Minimum Values:

Determine the maximum value (maxVal) and minimum value (minVal) in the array nums using the max_element and min_element functions.

3. Bucket Size Calculation:

Calculate the bucket size (bucketSize) as the maximum of 1 and the range of values divided by the number of elements minus 1. This ensures that there's at least one element in each bucket.

4. Bucket Count Calculation:

Calculate the number of buckets (bucketCount) by dividing the range of values by the bucket size and adding 1 to account for any remainder.

5. Bucket Creation and Distribution:

Create an array of pairs (buckets) to represent the buckets, where each pair stores the minimum and maximum values in a bucket.
Iterate through the elements in nums, calculate the index of the corresponding bucket, and update the bucket's minimum and maximum values.

6. Finding Maximum Gap:

Iterate through the buckets and calculate the maximum gap between buckets. The maximum gap occurs between the maximum value of the current bucket and the minimum value of the next non-empty bucket.
Update the maximum gap (maxGap) accordingly.

7. Return Result:

Return the maximum gap as the result.


__Time Complexity__ is $O(n)$

__Space Complexity__ is $O(n)$

<Tabs>
<TabItem value="cpp" label="C++">
<SolutionAuthor name="@sanchi1304"/>

```cpp

class Solution {
public:
int maximumGap(vector<int>& nums) {
if (nums.size() < 2) {
return 0;
}

int maxVal = *max_element(nums.begin(), nums.end());
int minVal = *min_element(nums.begin(), nums.end());
int bucketSize = max(1, (maxVal - minVal) / (int(nums.size()) - 1)); // Corrected line
int bucketCount = (maxVal - minVal) / bucketSize + 1;

// Create buckets
vector<pair<int, int>> buckets(bucketCount, {-1, -1});
for (int num : nums) {
int index = (num - minVal) / bucketSize;
if (buckets[index].first == -1) {
buckets[index].first = num;
buckets[index].second = num;
} else {
buckets[index].first = min(buckets[index].first, num);
buckets[index].second = max(buckets[index].second, num);
}
}

// Find maximum gap
int maxGap = 0;
int prevMax = minVal;
for (int i = 0; i < bucketCount; ++i) {
if (buckets[i].first == -1) {
continue; // Empty bucket
}
maxGap = max(maxGap, buckets[i].first - prevMax);
prevMax = buckets[i].second;
}

return maxGap;
}
};

```
</TabItem>
</Tabs>


## Approach 2: Using Pigeonhole Principle

1. Edge Case Check:

Start by checking if the input array nums has fewer than 2 elements. If so, return 0 since there are not enough elements to calculate a gap.

2. Find Maximum and Minimum Values:

Determine the maximum value (maxVal) and minimum value (minVal) in the array nums using the max_element and min_element functions.

3. Bucket Size Calculation:

Calculate the bucket size (bucketSize) as the maximum of 1 and the range of values divided by the number of elements minus 1. This ensures that there's at least one element in each bucket.

4. Bucket Count Calculation:

Calculate the number of buckets (bucketCount) by dividing the range of values by the bucket size and adding 1 to account for any remainder.

5. Bucket Creation and Distribution:

Create an array of pairs (buckets) to represent the buckets, where each pair stores the minimum and maximum values in a bucket.
Iterate through the elements in nums, calculate the index of the corresponding bucket, and update the bucket's minimum and maximum values.

6. Finding Maximum Gap:

Iterate through the buckets and calculate the maximum gap between buckets. The maximum gap occurs between the maximum value of the current bucket and the minimum value of the next non-empty bucket.
Update the maximum gap (maxGap) accordingly.

7. Return Result:

Return the maximum gap as the result.


__Time Complexity__ is $O(n)$

__Space Complexity__ is $O(n)$

<Tabs>
<TabItem value="cpp" label="C++">
<SolutionAuthor name="@sanchi1304"/>

```cpp

class Solution {
public:
int maximumGap(vector<int>& nums) {
if (nums.size() < 2) {
return 0;
}

int maxVal = *max_element(nums.begin(), nums.end());
int minVal = *min_element(nums.begin(), nums.end());
int bucketSize = max(1, (maxVal - minVal) / (int(nums.size()) - 1)); // Corrected line
int bucketCount = (maxVal - minVal) / bucketSize + 1;

// Create buckets
vector<pair<int, int>> buckets(bucketCount, {INT_MAX, INT_MIN});
for (int num : nums) {
int index = (num - minVal) / bucketSize;
buckets[index].first = min(buckets[index].first, num);
buckets[index].second = max(buckets[index].second, num);
}

// Find maximum gap
int maxGap = 0;
int prevMax = minVal;
for (int i = 0; i < bucketCount; ++i) {
if (buckets[i].first == INT_MAX) {
continue; // Empty bucket
}
maxGap = max(maxGap, buckets[i].first - prevMax);
prevMax = buckets[i].second;
}

return maxGap;
}
};

```
</TabItem>
</Tabs>
136 changes: 136 additions & 0 deletions solutions/0200-0299/0220-contains-duplicate-III.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
description: >-
Author: @Sanchita1304 |
https://leetcode.com/problems/contains-duplicate-iii/
---

# 0220 - Contains Duplicate III (Hard)

## Problem Link

https://leetcode.com/problems/contains-duplicate-iii/

## Problem Statement

You are given an integer array `nums` and two integers `indexDiff` and `valueDiff`.

Find a pair of indices `(i, j)` such that:

- `i != j`,
- `abs(i - j) <= indexDiff`.
- `abs(nums[i] - nums[j]) <= valueDiff`, and

Return true if such pair exists or false otherwise.

**Example 1:**

```
Input: nums = [1,2,3,1], indexDiff = 3, valueDiff = 0
Output: true

Explanation: We can choose (i, j) = (0, 3).
We satisfy the three conditions:
i != j --> 0 != 3
abs(i - j) <= indexDiff --> abs(0 - 3) <= 3
abs(nums[i] - nums[j]) <= valueDiff --> abs(1 - 1) <= 0
```

**Example 2:**

```
Input: nums = [1,5,9,1,5,9], indexDiff = 2, valueDiff = 3
Output: false

Explanation: After trying all the possible pairs (i, j), we cannot satisfy the three conditions, so we return false.
```

**Constraints:**

- `2 <= nums.length <= 105`
- `-109 <= nums[i] <= 109`
- `1 <= indexDiff <= nums.length`
- `0 <= valueDiff <= 109`

## Approach 1: Bucket Sort

1. Check for edge cases: If indexDiff is less than or equal to 0 or valueDiff is less than 0, return false as it's impossible to find a valid pair.

2. Initialize an unordered map buckets to store the mapping of bucket numbers to values.

3. Calculate the bucketWidth as valueDiff + 1. This determines the width of each bucket.

4. Iterate through the elements in the nums array.

5. For each element num, calculate the bucket number using the getBucket function. This function ensures that negative numbers are placed in different buckets.

6. Check if the current bucket is already in the buckets map. If yes, return true because you found a pair satisfying all conditions.

7. Check the neighboring buckets (previous and next) to see if there's a value within the valueDiff range. If yes, return true.

8. Update the buckets map with the current bucket and value.

9. If the index is greater than or equal to indexDiff, remove the earliest bucket to maintain the window size.

10. If no valid pair is found, return false after iterating through the entire array.

__Time Complexity__ is $O(n)$, where $n$ is the number of elements in the `nums` array.

__Space Complexity__ is $O(min(n, valueDiff))$, and in practice, it is often close to $O(n)$ when valueDiff is large.

<Tabs>
<TabItem value="cpp" label="C++">
<SolutionAuthor name="@sanchi1304"/>

```cpp

class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int indexDiff, int valueDiff) {
if (indexDiff <= 0 || valueDiff < 0) {
return false;
}

unordered_map<long long, long long> buckets; // Bucket number to value mapping
long long bucketWidth = static_cast<long long>(valueDiff) + 1;

for (int i = 0; i < nums.size(); ++i) {
long long num = static_cast<long long>(nums[i]);
long long bucket = getBucket(num, bucketWidth);

if (buckets.find(bucket) != buckets.end()) {
return true;
}

if (buckets.find(bucket - 1) != buckets.end() && num - buckets[bucket - 1] <= valueDiff) {
return true;
}

if (buckets.find(bucket + 1) != buckets.end() && buckets[bucket + 1] - num <= valueDiff) {
return true;
}

buckets[bucket] = num;

if (i >= indexDiff) {
long long removeBucket = getBucket(nums[i - indexDiff], bucketWidth);
buckets.erase(removeBucket);
}
}

return false;
}

private:
long long getBucket(long long num, long long bucketWidth) {
// Ensure negative numbers are placed in a different bucket
if (num < 0) {
return (num + 1) / bucketWidth - 1;
} else {
return num / bucketWidth;
}
}
};

```
</TabItem>
</Tabs>
Loading