Skip to content
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
@@ -0,0 +1,82 @@
/*
Problem: Binary Tree Maximum Path Sum
Platform: LeetCode
Problem Code: 124
Difficulty: Hard
Link: https://leetcode.com/problems/binary-tree-maximum-path-sum/

A path in a binary tree is a sequence of nodes where each pair of adjacent nodes
has an edge connecting them. A node can appear in the path at most once. The path
does not necessarily need to pass through the root.

The path sum of a path is the sum of the node's values in the path.

Given the root of a binary tree, return the maximum path sum of any non-empty path.

Example 1:
Input: root = [1,2,3]
Output: 6
Explanation: The optimal path is 2 → 1 → 3, which gives a path sum of 6.

Example 2:
Input: root = [-10,9,20,null,null,15,7]
Output: 42
Explanation: The optimal path is 15 → 20 → 7, which gives a path sum of 42.

Approach:
1. Use post-order DFS traversal to compute the maximum path sum passing through each node.
2. For every node, calculate:
- `l_sum`: maximum sum path in the left subtree.
- `r_sum`: maximum sum path in the right subtree.
3. The best path through the current node could include:
- only the node value,
- the node and left subtree,
- the node and right subtree,
- or both subtrees through the node.
4. Update a global `max_sum` with the maximum path found so far.
5. Return to the parent the maximum single-path sum (either left or right) plus current node value.

Time Complexity: O(n) — each node is visited once.
Space Complexity: O(h) — recursion stack, where h is the height of the tree.

Contributor: shwetakul2005
*/

#include <bits/stdc++.h>
using namespace std;

// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
int calc_sum(TreeNode* root, int& max_sum) {
if (root == NULL) return 0;

int l_sum = calc_sum(root->left, max_sum);
int r_sum = calc_sum(root->right, max_sum);

int c_sum = root->val;
if (l_sum > 0) c_sum += l_sum;
if (r_sum > 0) c_sum += r_sum;

// Update global maximum
max_sum = max(max_sum, c_sum);

// Return maximum path sum for parent usage
return max(0, max(l_sum, r_sum)) + root->val;
}

int maxPathSum(TreeNode* root) {
int max_sum = root->val;
calc_sum(root, max_sum);
return max_sum;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Problem: Insert into a Binary Search Tree
Platform: LeetCode
Problem Code: 701
Difficulty: Medium
Link: https://leetcode.com/problems/insert-into-a-binary-search-tree/

Given the root of a binary search tree (BST) and a value to insert into the tree,
insert the value into the BST. Return the root of the BST after the insertion.
It is guaranteed that the new value does not exist in the original BST.

Notice that there may exist multiple valid ways for the insertion, as long as the tree
remains a BST after insertion. You can return any of them.

Example 1:
Input: root = [4,2,7,1,3], val = 5
Output: [4,2,7,1,3,5]

Example 2:
Input: root = [40,20,60,10,30,50,70], val = 25
Output: [40,20,60,10,30,50,70,null,null,25]

Approach:
1. Recursively traverse the tree to find the correct position for the new value.
2. If the value is less than the current node, go to the left subtree.
3. If the value is greater, go to the right subtree.
4. When a NULL position is found, create a new node with the given value.
5. Return the root of the updated BST.

Time Complexity: O(h), where h is the height of the BST.
Space Complexity: O(h) due to recursion stack.

Contributor: shwetakul2005
*/

#include <bits/stdc++.h>
using namespace std;

// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == NULL) return new TreeNode(val);
if (val < root->val) root->left = insertIntoBST(root->left, val);
else root->right = insertIntoBST(root->right, val);
return root;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
Problem: Merge k Sorted Lists
Platform: LeetCode
Problem Code: 23
Difficulty: Hard
Link: https://leetcode.com/problems/merge-k-sorted-lists/

You are given an array of k linked-lists, each linked-list is sorted in ascending order.
Merge all the linked-lists into one sorted linked-list and return it.

Example 1:
Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]

Example 2:
Input: lists = []
Output: []

Example 3:
Input: lists = [[]]
Output: []

Approach:
1. Traverse through each linked list and push all node values into a min-heap (priority queue).
2. Extract the smallest element one by one from the heap to form a new sorted linked list.
3. This approach ensures a sorted result, though it uses extra memory for all node values.

Time Complexity: O(N log N) where N is the total number of nodes (since we push and pop each node in the heap).
Space Complexity: O(N) for storing all values in the priority queue.

Contributor: shwetakul2005
*/

#include <bits/stdc++.h>
using namespace std;

// Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
priority_queue<int, vector<int>, greater<int>> pq; // min-heap

// Step 1: Push all node values into heap
for (int i = 0; i < n; i++) {
ListNode* temp = lists[i];
while (temp != nullptr) {
pq.push(temp->val);
temp = temp->next;
}
}

// Step 2: Handle empty case
if (pq.empty()) return nullptr;

// Step 3: Construct the new sorted list
ListNode* res = new ListNode(pq.top());
pq.pop();
ListNode* temp = res;

while (!pq.empty()) {
temp->next = new ListNode(pq.top());
temp = temp->next;
pq.pop();
}

return res;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
Problem: Split Array Largest Sum
Platform: LeetCode
Problem Code: 410
Difficulty: Medium
Link: https://leetcode.com/problems/split-array-largest-sum/

Given an array `arr` of non-negative integers and an integer `m`, split the array into `m` non-empty continuous subarrays.
Write an algorithm to minimize the largest sum among these `m` subarrays.

Example 1:
Input: arr = [7,2,5,10,8], m = 2
Output: 18
Explanation: There are four ways to split arr into two subarrays. The best way is [7,2,5] and [10,8],
which has the largest sum = max(7+2+5,10+8) = 18.

Example 2:
Input: arr = [1,2,3,4,5], m = 2
Output: 9

Approach:
1. Use binary search on the range of possible sums:
- `low = max element of array` (minimum possible largest sum)
- `high = sum of array` (maximum possible largest sum)
2. For a candidate sum `mid`, check if it is possible to split the array into ≤ m subarrays such that no subarray sum exceeds `mid`.
3. If possible, try a smaller `mid` (move `high`), else increase `mid` (move `low`).
4. Continue until `low > high`, and the minimum feasible `mid` is the answer.

Time Complexity: O(n log(sum-max)), where sum-max = total sum of array minus max element.
Space Complexity: O(1) extra space.

Contributor: shwetakul2005
*/

#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
// Check if we can split array into ≤ m subarrays with max sum ≤ mid
bool ispos(vector<int>& v, int mid, int m) {
int n = v.size();
int s = 0, cnt = 0;

for (int i = 0; i < n; i++) {
s += v[i];
if (s == mid) {
cnt++;
s = 0;
}
else if (s > mid) {
cnt++;
s = v[i];
if (i == n - 1) {
cnt++;
}
}
else if (s < mid && i == n - 1) {
cnt++;
}
}

return cnt <= m;
}

int splitArray(vector<int>& arr, int m) {
int n = arr.size();
if (n < m) return -1;

int tot_sum = 0, maxi = INT_MIN;
for (int i = 0; i < n; i++) {
tot_sum += arr[i];
maxi = max(maxi, arr[i]);
}

int low = maxi, high = tot_sum;
int ans = tot_sum;

while (low <= high) {
int mid = low + (high - low) / 2;
if (ispos(arr, mid, m)) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}

return ans;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Problem: Trapping Rain Water
Platform: LeetCode
Problem Code: 42
Difficulty: Hard
Link: https://leetcode.com/problems/trapping-rain-water/

Given n non-negative integers representing an elevation map where the width of each bar is 1,
compute how much water it can trap after raining.

Example 1:
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1].
In this case, 6 units of rain water (blue section) are being trapped.

Example 2:
Input: height = [4,2,0,3,2,5]
Output: 9

Approach:
1. Use two pointers — one from the left and one from the right.
2. Maintain two variables `leftMax` and `rightMax` to store the maximum height encountered so far from each side.
3. Move the pointer with the smaller height inward.
- If the current height is less than the corresponding max, water can be trapped = max - height.
- Otherwise, update the max height.
4. Continue until both pointers meet.
5. This approach eliminates the need for extra arrays and efficiently computes the trapped water.

Time Complexity: O(n)
Space Complexity: O(1)

Contributor: shwetakul2005
*/

#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
if (n == 0) return 0;

int left = 0, right = n - 1;
int leftMax = 0, rightMax = 0;
int water = 0;

while (left < right) {
if (height[left] < height[right]) {
// Update left max
if (height[left] >= leftMax)
leftMax = height[left];
else
water += leftMax - height[left];
left++;
}
else {
// Update right max
if (height[right] >= rightMax)
rightMax = height[right];
else
water += rightMax - height[right];
right--;
}
}
return water;
}
};
Loading
Loading