-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
95b42f1
commit b81a8e9
Showing
19 changed files
with
613 additions
and
16 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
116 changes: 116 additions & 0 deletions
116
Algorithms/Searching-Algorithms/Binary-Search/Medium/koko-eating-bananas.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
## KOKO Eating Bananas | ||
|
||
**Problem Statement:** A monkey is given `n` piles of bananas, whereas the `ith` pile has `a[i]` bananas. An integer `h` is also given, which denotes the time (in hours) for all the bananas to be eaten. | ||
|
||
Each hour, the monkey chooses a non-empty pile of bananas and eats `k` bananas. If the pile contains less than `k` bananas, then the monkey consumes all the bananas and won’t eat any more bananas in that hour. | ||
|
||
Find the minimum number of bananas `k` to eat per hour so that the monkey can eat all the bananas within `h` hours. | ||
|
||
--- | ||
|
||
### Examples | ||
|
||
Example 1: | ||
Input Format: N = 4, a[] = {7, 15, 6, 3}, h = 8 | ||
Result: 5 | ||
Explanation: If Koko eats 5 bananas/hr, he will take 2, 3, 2, and 1 hour to eat the piles accordingly. So, he will take 8 hours to complete all the piles. | ||
|
||
--- | ||
|
||
Example 2: | ||
Input Format: N = 5, a[] = {25, 12, 8, 14, 19}, h = 5 | ||
Result: 25 | ||
Explanation: If Koko eats 25 bananas/hr, he will take 1, 1, 1, 1, and 1 hour to eat the piles accordingly. So, he will take 5 hours to complete all the piles. | ||
|
||
--- | ||
|
||
Before moving on to the solution, let’s understand how Koko will eat the bananas. Assume, the given array is {3, 6, 7, 11} and the given time i.e. h is 8. | ||
|
||
First of all, Koko cannot eat bananas from different piles. He should complete the pile he has chosen and then he can go for another pile. | ||
Now, Koko decides to eat 2 bananas/hour. So, in order to complete the first he will take | ||
3 / 2 = 2 hours. Though mathematically, he should take 1.5 hrs but it is clearly stated in the question that after completing a pile Koko will not consume more bananas in that hour. So, for the first pile, Koko will eat 2 bananas in the first hour and then he will consume 1 banana in another hour. | ||
|
||
From here we can conclude that we have to take ceil of (3/2). Similarly, we will calculate the times for other piles. | ||
|
||
1st pile: ceil(3/2) = 2 hrs | ||
2nd pile: ceil(6/2) = 3 hrs | ||
3rd pile: ceil(7/2) = 4 hrs | ||
4th pile: ceil(11/2) = 6 hrs | ||
|
||
Koko will take 15 hrs in total to consume all the bananas from all the piles. | ||
|
||
--- | ||
|
||
**Observation**: Upon observation, it becomes evident that the maximum number of bananas (represented by 'k') that Koko can consume in an hour is obtained from the pile that contains the largest quantity of bananas. Therefore, the maximum value of 'k' corresponds to the maximum element present in the given array. | ||
|
||
So, our answer i.e. the minimum value of ‘k’ lies between 1 and the maximum element in the array i.e. max(a[]). | ||
|
||
--- | ||
|
||
### Solution : | ||
|
||
```cpp | ||
#include <bits/stdc++.h> | ||
using namespace std; | ||
|
||
long long calculateTotalHours(vector<int> &v, long long hourly) { | ||
long long totalH = 0; | ||
int n = v.size(); | ||
for (int i = 0; i < n; i++) { | ||
totalH += (v[i] + hourly - 1) / hourly; | ||
} | ||
return totalH; | ||
} | ||
|
||
long long minimumRateToEatBananas(vector<int> &v, long long h) { | ||
long long low = 1, high = INT_MAX; | ||
|
||
while (low < high) { | ||
long long mid = low + (high - low) / 2; | ||
long long totalH = calculateTotalHours(v, mid); | ||
|
||
if (totalH <= h) { | ||
high = mid; | ||
} else { | ||
low = mid + 1; | ||
} | ||
} | ||
return low; | ||
} | ||
``` | ||
--- | ||
### Explanation : | ||
1. `calculateTotalHours` : | ||
This function calculates the total hours required to eat all the bananas at a given hourly rate. It uses integer division and rounds up to the nearest integer using `(v[i] + hourly - 1) / hourly`. | ||
2. `minimumRateToEatBananas` : | ||
This function performs a **binary search** to find the minimum hourly rate required to eat all the bananas within h hours. It initializes a `low` rate as 1 and a `high` rate as a large integer. | ||
The binary search continues until low is less than high, and it updates the `mid` rate within this range. | ||
It then calculates the total hours required at the mid rate using the calculateTotalHours function. If the total hours are less than or equal to h, it updates high to mid, effectively searching in the lower half of the range; otherwise, it updates low to mid + 1, searching in the upper half. | ||
--- | ||
The expression `(v[i] + hourly - 1) / hourly` with an example: | ||
Suppose we have the following values: | ||
v[i] (the number of bananas to eat) = 12 | ||
hourly (the hourly rate at which we can eat) = 5 | ||
Using the expression `(v[i] + hourly - 1) / hourly`: | ||
(12 + 5 - 1) / 5 | ||
(16) / 5 | ||
3.2 | ||
Now, let's break it down: | ||
12 + 5 - 1 equals 16. This step ensures that we add hourly - 1 to the numerator, which is necessary to ensure rounding up. | ||
16 / 5 equals 3.2. This is the result of dividing the numerator (16) by the denominator (5). | ||
In this example, the result of `(v[i] + hourly - 1) / hourly` is 3.2. Since we want to round up to the nearest integer (**because you can't eat a fraction of a banana**), this value would be considered as 4 hours required to eat 12 bananas at a rate of 5 bananas per hour. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
Data-Structures/Linear-Data-Structures/Linked-List/02-insertion.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
## Insertion in a Linked List. | ||
|
||
### 1. Insertion at head | ||
|
||
**Steps :** | ||
|
||
1. Make a `void` function which accepts a reference to a head pointer and a data as parameter. | ||
2. Make a new temporary Node which accepts the data parameter. | ||
3. Then point the temp node's next pointer to the current head. | ||
4. Finally temp becomes our new head pointer. | ||
|
||
--- | ||
|
||
### 2. Insertion at tail | ||
|
||
**Steps :** | ||
|
||
1. Make a `void` function which accepts a reference to a tail pointer and a data as parameter. | ||
2. Make a new temporary Node which accepts the data parameter. | ||
3. Then point the tail node's next pointer to the temp node. | ||
4. Finally temp becomes our new tail pointer. | ||
|
||
--- | ||
|
||
### 2. Insertion at any position | ||
|
||
**Steps :** | ||
|
||
1. Make a `void` function which accepts a reference to head & tail pointer and a position & data as parameter. | ||
2. Make a temp node which'll initially point to head. | ||
3. | ||
4. | ||
--- | ||
|
||
### Implementation : | ||
|
||
```cpp | ||
#include <bits/stdc++.h> | ||
#include <cstddef> | ||
using namespace std; | ||
|
||
class Node { | ||
public: | ||
int data; | ||
Node *next; | ||
|
||
Node(int data) { | ||
this->data = data; | ||
this->next = NULL; | ||
} | ||
}; | ||
|
||
void insertAtHead(Node *&head, int data) { | ||
Node *temp = new Node(data); | ||
temp->next = head; | ||
head = temp; | ||
} | ||
|
||
void insertAtTail(Node *&tail, int data) { | ||
Node *temp = new Node(data); | ||
tail->next = temp; | ||
tail = temp; | ||
} | ||
|
||
void insertAtPosition(Node *&head, Node *&tail, int pos, int data) { | ||
Node *temp = head; | ||
int cnt = 1; | ||
|
||
// if inserting at first pos | ||
if (pos == 1) { | ||
insertAtHead(head, data); | ||
return; | ||
} | ||
|
||
// if inserting at last pos | ||
if (temp->next == NULL) { | ||
insertAtTail(tail, data); | ||
return; | ||
} | ||
|
||
while (cnt < pos - 1) { | ||
temp = temp->next; | ||
cnt++; | ||
} | ||
|
||
Node *nodeToInsert = new Node(data); | ||
nodeToInsert->next = temp->next; | ||
temp->next = nodeToInsert; | ||
} | ||
|
||
void printLinkedList(Node *&head) { | ||
Node *temp = head; | ||
while (temp != NULL) { | ||
cout << temp->data << " "; | ||
temp = temp->next; | ||
} | ||
cout << endl; | ||
} | ||
|
||
int main() { | ||
Node *node1 = new Node(10); | ||
|
||
// create head and tail pointer. | ||
Node *head = node1; | ||
Node *tail = node1; | ||
|
||
cout << "Initial List : "; | ||
printLinkedList(head); | ||
|
||
insertAtHead(head, 12); | ||
|
||
cout << "List after insertion at head : "; | ||
printLinkedList(head); | ||
|
||
insertAtTail(tail, 13); | ||
|
||
cout << "List after insertion at tail : "; | ||
printLinkedList(head); | ||
|
||
insertAtPosition(head, tail, 3, 14); | ||
|
||
cout << "List after insertion at 3rd position : "; | ||
printLinkedList(head); | ||
return 0; | ||
} | ||
``` | ||
``` | ||
Output : | ||
Initial List : 10 | ||
List after insertion at head : 12 10 | ||
List after insertion at tail : 12 10 13 | ||
List after insertion at 3rd position : 12 10 14 13 | ||
``` | ||
--- |
49 changes: 49 additions & 0 deletions
49
Data-Structures/Linear-Data-Structures/Linked-List/reverseLinkedList.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
## Reverse a Linked List | ||
|
||
### Approach : | ||
|
||
1. Initialize prev to nullptr and current to the head of the original linked list. | ||
2. Enter a while loop that terminates when current is nullptr. | ||
3. Inside the while loop, do the following: | ||
- Store the next node in the original linked list in next. | ||
- Update the next pointer of the current node to point to the previous node. | ||
- Update the prev pointer to point to the current node. | ||
- Update the current pointer to point to the next node. | ||
4. Return prev, which is now the head of the reversed linked list. | ||
|
||
--- | ||
|
||
### Imlementation : | ||
|
||
```cpp | ||
#include <bits/stdc++.h> | ||
using namespace std; | ||
|
||
template <typename T> class LinkedListNode { | ||
public: | ||
T data; | ||
LinkedListNode<T> *next; | ||
LinkedListNode(T data) { | ||
this->data = data; | ||
this->next = NULL; | ||
} | ||
}; | ||
|
||
// Solution :- | ||
LinkedListNode<int> *reverseLinkedList(LinkedListNode<int> *head) { | ||
|
||
LinkedListNode<int> *prev = nullptr; | ||
LinkedListNode<int> *current = head; | ||
LinkedListNode<int> *next = nullptr; | ||
|
||
while (current != nullptr) { | ||
next = current->next; | ||
current->next = prev; | ||
prev = current; | ||
current = next; | ||
} | ||
return prev; | ||
} | ||
|
||
int main() { return 0; } | ||
``` |
Oops, something went wrong.