diff --git a/dsa-solutions/lc-solutions/0100-0199/0141-linked-list-cycle.md b/dsa-solutions/lc-solutions/0100-0199/0141-linked-list-cycle.md new file mode 100644 index 000000000..c2e8a9882 --- /dev/null +++ b/dsa-solutions/lc-solutions/0100-0199/0141-linked-list-cycle.md @@ -0,0 +1,157 @@ +--- +id: linked-list-cycle +title: Linked List Cycle +sidebar_label: 0141- Linked List Cycle +tags: + - DSA + - Leetcode + - Linked List + +description: "This is a solution to the Linked List cycle on LeetCode." +--- + +## Problem Statement + +Given head, the head of a linked list, determine if the linked list has a cycle in it. + +There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter. + +Return true if there is a cycle in the linked list. Otherwise, return false. + +### Examples + +**Example 1:** + +``` +Input: head = [3,2,0,-4], pos = 1 +Output: true +Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed). +``` + +**Example 2:** + +``` +Input: head = [1,2], pos = 0 +Output: true +Explanation: There is a cycle in the linked list, where the tail connects to the 0th node. +``` + +**Example 3:** + +``` +Input: head = [1], pos = -1 +Output: false +Explanation: There is no cycle in the linked list. +``` + +### Constraints: + +- The number of the nodes in the list is in the range $[0, 10^4].$ +- $-105 <= Node.val <= 105$ +- $pos is -1 or a valid index in the linked-list.$ + +## Algorithm + +1. **Initialization**: + + - Initialize two pointers, `slow` and `fast`, both pointing to the head of the linked list. + +2. **Traversal**: + + - Move the `slow` pointer one step at a time. + - Move the `fast` pointer two steps at a time. + +3. **Cycle Detection**: + + - If there is a cycle, the `fast` pointer will eventually meet the `slow` pointer within the cycle. + - If there is no cycle, the `fast` pointer will reach the end of the list (NULL). + +4. **Return Result**: + - If the `fast` pointer meets the `slow` pointer, return `true` indicating a cycle is detected. + - If the `fast` pointer reaches the end of the list, return `false` indicating no cycle is detected. + +## Code Implementation + +### C++ + +```cpp +class Solution { +public: + bool hasCycle(ListNode *head) { + ListNode* fast = head; + ListNode* slow = head; + + while (fast != NULL && fast->next != NULL) { + fast = fast->next->next; + slow = slow->next; + if (fast == slow) { + return true; + } + } + + return false; + } +}; +``` + +### Python + +```python +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class Solution: + def hasCycle(self, head: ListNode) -> bool: + fast = head + slow = head + + while fast is not None and fast.next is not None: + fast = fast.next.next + slow = slow.next + if fast == slow: + return True + + return False +``` + +### Java + +```java +public class Solution { + public boolean hasCycle(ListNode head) { + ListNode fast = head; + ListNode slow = head; + + while (fast != null && fast.next != null) { + fast = fast.next.next; + slow = slow.next; + if (fast == slow) { + return true; + } + } + + return false; + } +} +``` + +### JavaScript + +```javascript +var hasCycle = function (head) { + let fast = head; + let slow = head; + + while (fast !== null && fast.next !== null) { + fast = fast.next.next; + slow = slow.next; + if (fast === slow) { + return true; + } + } + + return false; +}; +``` diff --git a/dsa-solutions/lc-solutions/0100-0199/0142-linked-list-cycle-II.md b/dsa-solutions/lc-solutions/0100-0199/0142-linked-list-cycle-II.md new file mode 100644 index 000000000..9cb15f869 --- /dev/null +++ b/dsa-solutions/lc-solutions/0100-0199/0142-linked-list-cycle-II.md @@ -0,0 +1,174 @@ +--- +id: linked-list-cycle--II +title: Linked List Cycle II +sidebar_label: 0142- Linked List Cycle II +tags: + - DSA + - Leetcode + - Linked List + +description: "This is a solution to the Linked List cycle II on LeetCode." +--- + +## Problem Statement + +Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null. + +There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to (0-indexed). It is -1 if there is no cycle. Note that pos is not passed as a parameter. + +Do not modify the linked list. + +### Examples + +**Example 1:** + +``` +Input: head = [3,2,0,-4], pos = 1 +Output: tail connects to node index 1 +Explanation: There is a cycle in the linked list, where tail connects to the second node. +``` + +**Example 2:** + +``` +Input: head = [1,2], pos = 0 +Output: tail connects to node index 0 +Explanation: There is a cycle in the linked list, where tail connects to the first node. +``` + +**Example 3:** + +``` +Input: head = [1], pos = -1 +Output: no cycle +Explanation: There is no cycle in the linked list. +``` + +### Constraints: + +- The number of the nodes in the list is in the range $[0, 10^4].$ +- $-10^5 <= Node.val <= 10^5$ +- pos is `-1` or a valid index in the linked-list. + +## Algorithm for Detecting the Start of a Cycle in a Linked List + +1. **Initialization**: + + - Initialize two pointers, `slow` and `fast`, both pointing to the head of the linked list. + +2. **Cycle Detection**: + + - Move the `slow` pointer one step at a time. + - Move the `fast` pointer two steps at a time. + - If there is a cycle, the `fast` pointer will eventually meet the `slow` pointer within the cycle. + +3. **Finding the Cycle Start**: + + - If the `fast` pointer meets the `slow` pointer, reset the `slow` pointer to the head of the list. + - Move both pointers one step at a time until they meet again. + - The node where they meet is the start of the cycle. + +4. **Return Result**: + - If the `fast` pointer meets the `slow` pointer, return the meeting node. + - If there is no cycle, return `NULL`. + +## Code Implementations + +### C++ + +```cpp +class Solution { +public: + ListNode *detectCycle(ListNode *head) { + ListNode* fast = head; + ListNode* slow = head; + + while (fast != NULL && fast->next != NULL) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) { + slow = head; + while (slow != fast) { + slow = slow->next; + fast = fast->next; + } + return slow; + } + } + return NULL; + } +}; +``` + +### Python + +```python +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class Solution: + def detectCycle(self, head: ListNode) -> ListNode: + fast = head + slow = head + + while fast is not None and fast.next is not None: + slow = slow.next + fast = fast.next.next + if slow == fast: + slow = head + while slow != fast: + slow = slow.next + fast = fast.next + return slow + return None +``` + +### Java + +```java +public class Solution { + public ListNode detectCycle(ListNode head) { + ListNode fast = head; + ListNode slow = head; + + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) { + slow = head; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + return slow; + } + } + return null; + } +} +``` + +### JavaScript + +```javascript +var detectCycle = function (head) { + let fast = head; + let slow = head; + + while (fast !== null && fast.next !== null) { + slow = slow.next; + fast = fast.next.next; + if (slow === fast) { + slow = head; + while (slow !== fast) { + slow = slow.next; + fast = fast.next; + } + return slow; + } + } + return null; +}; +``` diff --git a/dsa-solutions/lc-solutions/0100-0199/0148-sort-list.md b/dsa-solutions/lc-solutions/0100-0199/0148-sort-list.md new file mode 100644 index 000000000..41f9491d2 --- /dev/null +++ b/dsa-solutions/lc-solutions/0100-0199/0148-sort-list.md @@ -0,0 +1,266 @@ +--- +id: sort-list +title: Sort List +sidebar_label: 0148- Sort List +tags: + - DSA + - Leetcode + - Linked List + +description: "This is a solution to the Sort List on LeetCode." +--- + +## Problem Statement + +Given the head of a linked list, return the list after sorting it in ascending order. + +**Example 1:** + +``` +Input: head = [4,2,1,3] +Output: [1,2,3,4] +``` + +**Example 2:** + +``` +Input: head = [-1,5,3,4,0] +Output: [-1,0,3,4,5] +``` + +**Example 3:** + +``` +Input: head = [] +Output: [] +``` + +### Constraints: + +- The number of nodes in the list is in the range $[0, 5 * 10^4].$ +- $-10^5 <= Node.val <= 10^5$ + +## Algorithm + +The algorithm uses the merge sort technique to sort a singly linked list. The steps involved are as follows: + +1. **Base Case**: + + - If the list is empty or contains only one element, it is already sorted. Return the head. + +2. **Splitting the List**: + + - Use two pointers, `slow` and `fast`, to find the middle of the list. + - Move `slow` one step at a time and `fast` two steps at a time. + - When `fast` reaches the end of the list, `slow` will be at the middle. + - Split the list into two halves at the middle. + +3. **Recursive Sorting**: + + - Recursively sort the two halves. + +4. **Merging**: + - Merge the two sorted halves into a single sorted list. + +## C++ Implementation + +```cpp +class Solution { +public: + ListNode* sortList(ListNode* head) { + if (head == NULL || head->next == NULL) + return head; + + ListNode *temp = NULL; + ListNode *slow = head; + ListNode *fast = head; + + while (fast != NULL && fast->next != NULL) { + temp = slow; + slow = slow->next; + fast = fast->next->next; + } + temp->next = NULL; + + ListNode* l1 = sortList(head); + ListNode* l2 = sortList(slow); + + return merge(l1, l2); + } + + ListNode* merge(ListNode *l1, ListNode *l2) { + ListNode *ptr = new ListNode(0); + ListNode *curr = ptr; + + while (l1 != NULL && l2 != NULL) { + if (l1->val <= l2->val) { + curr->next = l1; + l1 = l1->next; + } else { + curr->next = l2; + l2 = l2->next; + } + curr = curr->next; + } + if (l1 != NULL) { + curr->next = l1; + } + if (l2 != NULL) { + curr->next = l2; + } + return ptr->next; + } +}; +``` + +## Python Implementation + +```python +class ListNode: + def __init__(self, x=0, next=None): + self.val = x + self.next = next + +class Solution: + def sortList(self, head: ListNode) -> ListNode: + if not head or not head.next: + return head + + # Find the middle point + slow, fast = head, head + prev = None + while fast and fast.next: + prev = slow + slow = slow.next + fast = fast.next.next + + # Split the list into two halves + prev.next = None + + # Recursively sort the two halves + l1 = self.sortList(head) + l2 = self.sortList(slow) + + # Merge the sorted halves + return self.merge(l1, l2) + + def merge(self, l1: ListNode, l2: ListNode) -> ListNode: + dummy = ListNode() + curr = dummy + + while l1 and l2: + if l1.val <= l2.val: + curr.next = l1 + l1 = l1.next + else: + curr.next = l2 + l2 = l2.next + curr = curr.next + + if l1: + curr.next = l1 + if l2: + curr.next = l2 + + return dummy.next +``` + +## Java Implementation + +```java +class Solution { + public ListNode sortList(ListNode head) { + if (head == null || head.next == null) + return head; + + ListNode slow = head, fast = head, temp = null; + + while (fast != null && fast.next != null) { + temp = slow; + slow = slow.next; + fast = fast.next.next; + } + temp.next = null; + + ListNode l1 = sortList(head); + ListNode l2 = sortList(slow); + + return merge(l1, l2); + } + + private ListNode merge(ListNode l1, ListNode l2) { + ListNode dummy = new ListNode(0); + ListNode curr = dummy; + + while (l1 != null && l2 != null) { + if (l1.val <= l2.val) { + curr.next = l1; + l1 = l1.next; + } else { + curr.next = l2; + l2 = l2.next; + } + curr = curr.next; + } + if (l1 != null) { + curr.next = l1; + } + if (l2 != null) { + curr.next = l2; + } + return dummy.next; + } +} +``` + +## JavaScript Implementation + +```javascript +function ListNode(val, next = null) { + this.val = val; + this.next = next; +} + +var sortList = function (head) { + if (!head || !head.next) return head; + + let slow = head, + fast = head, + temp = null; + + while (fast && fast.next) { + temp = slow; + slow = slow.next; + fast = fast.next.next; + } + temp.next = null; + + const l1 = sortList(head); + const l2 = sortList(slow); + + return merge(l1, l2); +}; + +function merge(l1, l2) { + const dummy = new ListNode(0); + let curr = dummy; + + while (l1 && l2) { + if (l1.val <= l2.val) { + curr.next = l1; + l1 = l1.next; + } else { + curr.next = l2; + l2 = l2.next; + } + curr = curr.next; + } + if (l1) { + curr.next = l1; + } + if (l2) { + curr.next = l2; + } + return dummy.next; +} +``` diff --git a/dsa-solutions/lc-solutions/0100-0199/0149-max-points-on-a-line.md b/dsa-solutions/lc-solutions/0100-0199/0149-max-points-on-a-line.md new file mode 100644 index 000000000..92bfcf6fc --- /dev/null +++ b/dsa-solutions/lc-solutions/0100-0199/0149-max-points-on-a-line.md @@ -0,0 +1,179 @@ +--- +id: max-points-on-a-line.md +title: Max Points on a Line +sidebar_label: 0149- Max Points on a Line +tags: + - Leetcode +description: "This is a solution to the Max Point on a Line on LeetCode." +--- + +### Problem Satement + +Given an array of points where points[i] = [xi, yi] represents a point on the X-Y plane, return the maximum number of points that lie on the same straight line. + +### Examples + +**Example 1:** + +``` +Input: points = [[1,1],[2,2],[3,3]] +Output: 3 +``` + +**Example 2:** + +``` +Input: points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] +Output: 4 +``` + +### Constraints: + +- $1 <= points.length <= 300$ +- $points[i].length == 2$ +- $-10^4 <= xi, yi <= 10^4$ +- All the points are unique. + +### Algorithm Explanation + +1. **Input Handling**: + + - If there are 2 or fewer points, all points will always lie on the same line, so we can directly return the number of points. + +2. **Initialization**: + + - Initialize `maxi` to 2, since at least two points can define a line. + +3. **Iterate through each pair of points**: + + - Use a nested loop to select pairs of points `(i, j)` where `i < j`. + +4. **Count points on the line**: + + - For each pair `(i, j)`, initialize a count of 2 (since the pair itself constitutes two points on the line). + - Check every other point `k` to see if it lies on the line defined by `(i, j)`. + - To determine if three points are collinear, use the slope comparison: + `(y2 - y1) \times (x1 - x3) = (y1 - y3) \times (x2 - x1)` + This equation avoids division and thus floating-point inaccuracies. + +5. **Update Maximum Count**: + + - Update `maxi` if the current line defined by points `(i, j)` has more points than the previously recorded maximum. + +6. **Return Result**: + - After checking all pairs, return the maximum number of collinear points found. + +### Code Implementation + +#### C++ Implementation + +```cpp +class Solution { +public: + int maxPoints(vector>& points) { + int n = points.size(); + + if(n <= 2) + return n; + + int maxi = 2; + for(int i = 0; i < n; i++) { + for(int j = i + 1; j < n; j++) { + int count = 2; + for(int k = 0; k < n; k++) { + if(k != i && k != j) { + if((points[j][1] - points[i][1]) * (points[i][0] - points[k][0]) == + (points[i][1] - points[k][1]) * (points[j][0] - points[i][0])) { + count++; + } + } + } + maxi = max(maxi, count); + } + } + return maxi; + } +}; +``` + +#### Python Implementation + +```python +class Solution: + def maxPoints(self, points: List[List[int]]) -> int: + n = len(points) + + if n <= 2: + return n + + maxi = 2 + for i in range(n): + for j in range(i + 1, n): + count = 2 + for k in range(n): + if k != i and k != j: + if (points[j][1] - points[i][1]) * (points[i][0] - points[k][0]) == \ + (points[i][1] - points[k][1]) * (points[j][0] - points[i][0]): + count += 1 + maxi = max(maxi, count) + return maxi +``` + +#### Java Implementation + +```java +class Solution { + public int maxPoints(int[][] points) { + int n = points.length; + + if (n <= 2) + return n; + + int maxi = 2; + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + int count = 2; + for (int k = 0; k < n; k++) { + if (k != i && k != j) { + if ((points[j][1] - points[i][1]) * (points[i][0] - points[k][0]) == + (points[i][1] - points[k][1]) * (points[j][0] - points[i][0])) { + count++; + } + } + } + maxi = Math.max(maxi, count); + } + } + return maxi; + } +} +``` + +#### JavaScript Implementation + +```javascript +var maxPoints = function (points) { + let n = points.length; + + if (n <= 2) return n; + + let maxi = 2; + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + let count = 2; + for (let k = 0; k < n; k++) { + if (k !== i && k !== j) { + if ( + (points[j][1] - points[i][1]) * (points[i][0] - points[k][0]) === + (points[i][1] - points[k][1]) * (points[j][0] - points[i][0]) + ) { + count++; + } + } + } + maxi = Math.max(maxi, count); + } + } + return maxi; +}; +```