53.
Maximum Subarray
Given an integer array nums, find the subarray with the
largest sum, and return its sum.
Example 1:
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: The subarray [4,-1,2,1] has the largest sum
6.
Example 2:
Input: nums = [1]
Output: 1
Explanation: The subarray [1] has the largest sum 1.
Example 3:
Input: nums = [5,4,-1,7,8]
Output: 23
Explanation: The subarray [5,4,-1,7,8] has the largest
sum 23.
Constraints:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
Follow up: If you have figured out the O(n) solution, try
coding another solution using the divide and conquer
approach, which is more subtle.
Solution
#include <stdio.h>
#include <stdlib.h>
// Function to find the maximum subarray sum using
Kadane's algorithm
int maxSubArray(int* nums, int numsSize) {
int sum1 = nums[0], sum2 = nums[0];
for (int i = 1; i < numsSize; i++) {
if (sum1 + nums[i] > nums[i])
sum1 = sum1 + nums[i];
else
sum1 = nums[i];
if (sum1 > sum2)
sum2 = sum1;
}
return sum2;
}
int main() {
int numsSize;
// Read the size of the array
printf("Enter the size of the array: ");
scanf("%d", &numsSize);
// Allocate memory for the array
int* nums = (int*)malloc(numsSize * sizeof(int));
// Read the elements of the array
printf("Enter the elements of the array: ");
for (int i = 0; i < numsSize; i++)
scanf("%d", &nums[i]);
// Find and print the maximum subarray sum
int maxSum = maxSubArray(nums, numsSize);
printf("The maximum subarray sum is: %d\n", maxSum);
// Free the allocated memory
free(nums);
return 0;
}
4. Median of Two Sorted Arrays
Given two sorted arrays nums1 and nums2 of size m and n
respectively, return the median of the two sorted arrays.
The overall run time complexity should be O(log (m+n)).
Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 +
3) / 2 = 2.5.
Constraints:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
Solution
#include <stdio.h>
#include <stdlib.h>
// Function to find the median of two sorted arrays
double findMedianSortedArrays(int* nums1, int m, int*
nums2, int n) {
// Ensure nums1 is the smaller array
if (m > n)
return findMedianSortedArrays(nums2, n, nums1, m);
int imin = 0, imax = m, half_len = (m + n + 1) / 2;
while (imin <= imax) {
int i = (imin + imax) / 2;
int j = half_len - i;
if (i < m && nums1[i] < nums2[j - 1])
imin = i + 1; // i is too small, must
increase it
else if (i > 0 && nums1[i - 1] > nums2[j])
imax = i - 1; // i is too big, must decrease
it
else { // i is perfect
int max_of_left;
if (i == 0)
max_of_left = nums2[j - 1];
else if (j == 0)
max_of_left = nums1[i - 1];
else
max_of_left = (nums1[i - 1] > nums2[j -
1]) ? nums1[i - 1] : nums2[j - 1];
if ((m + n) % 2 == 1)
return max_of_left;
int min_of_right;
if (i == m)
min_of_right = nums2[j];
else if (j == n)
min_of_right = nums1[i];
else
min_of_right = (nums1[i] < nums2[j]) ?
nums1[i] : nums2[j];
return (max_of_left + min_of_right) / 2.0;
}
}
return 0.0; // Should never be reached
}
int main() {
int m, n;
// Read the size of the first array
printf("Enter the size of the first array: ");
scanf("%d", &m);
// Allocate memory for the first array
int* nums1 = (int*)malloc(m * sizeof(int));
// Read the elements of the first array
printf("Enter the elements of the first array: ");
for (int i = 0; i < m; i++)
scanf("%d", &nums1[i]);
// Read the size of the second array
printf("Enter the size of the second array: ");
scanf("%d", &n);
// Allocate memory for the second array
int* nums2 = (int*)malloc(n * sizeof(int));
// Read the elements of the second array
printf("Enter the elements of the second array: ");
for (int i = 0; i < n; i++)
scanf("%d", &nums2[i]);
// Find and print the median of the two sorted arrays
double median = findMedianSortedArrays(nums1, m,
nums2, n);
printf("The median of the two sorted arrays
is: %.5f\n", median);
// Free the allocated memory
free(nums1);
free(nums2);
return 0;
}
11. Container With Most Water
You are given an integer array height of length n. There
are n vertical lines drawn such that the two endpoints of
the ith line are (i, 0) and (i, height[i]).
Find two lines that together with the x-axis form a
container, such that the container contains the most
water.
Return the maximum amount of water a container can store.
Notice that you may not slant the container.
Example 1:
Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49
Explanation: The above vertical lines are represented by
array [1,8,6,2,5,4,8,3,7]. In this case, the max area of
water (blue section) the container can contain is 49.
Example 2:
Input: height = [1,1]
Output: 1
Constraints:
n == height.length
2 <= n <= 105
0 <= height[i] <= 104
Solution
#include <stdio.h>
#include <stdlib.h>
// Function to find the maximum area
int maxArea(int* height, int heightSize) {
int left = 0;
int right = heightSize - 1;
int maxArea = 0;
while (left < right) {
int currentArea = (right - left) * (height[left]
< height[right] ? height[left] : height[right]);
if (currentArea > maxArea)
maxArea = currentArea;
if (height[left] < height[right])
left++;
else
right--;
}
return maxArea;
}
int main() {
int n;
// Read the size of the array
printf("Enter the number of elements: ");
scanf("%d", &n);
// Allocate memory for the array
int* height = (int*)malloc(n * sizeof(int));
// Read the elements of the array
printf("Enter the heights: ");
for (int i = 0; i < n; i++)
scanf("%d", &height[i]);
// Find and print the maximum area
int max_area = maxArea(height, n);
printf("The maximum area is: %d\n", max_area);
// Free the allocated memory
free(height);
return 0;
}
215. Kth Largest Element in an Array
Given an integer array nums and an integer k, return the
kth largest element in the array.
Note that it is the kth largest element in the sorted
order, not the kth distinct element.
Can you solve it without sorting?
Example 1:
Input: nums = [3,2,1,5,6,4], k = 2
Output: 5
Example 2:
Input: nums = [3,2,3,1,2,4,5,5,6], k = 4
Output: 4
Constraints:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
Solution
#include <stdio.h>
#include <stdlib.h>
// Function to maintain the min-heap property
void heapify(int* heap, int heapSize, int i) {
int smallest = i; // Initialize smallest as root
int left = 2 * i + 1; // Left child
int right = 2 * i + 2; // Right child
// If left child is smaller than root
if (left < heapSize && heap[left] < heap[smallest])
smallest = left;
// If right child is smaller than the smallest so far
if (right < heapSize && heap[right] < heap[smallest])
smallest = right;
// If the smallest is not root
if (smallest != i) {
// Swap values using XOR swap
heap[i] ^= heap[smallest] ^= heap[i] ^=
heap[smallest];
// Recursively heapify the affected sub-tree
heapify(heap, heapSize, smallest);
}
}
// Function to build a min-heap from the first k elements
void buildMinHeap(int* heap, int heapSize) {
// Build heap (rearrange array)
for (int i = heapSize / 2 - 1; i >= 0; i--)
heapify(heap, heapSize, i);
}
// Function to find the kth largest element in the array
int findKthLargest(int* nums, int numsSize, int k) {
// Allocate memory for a heap of size k
int* heap = (int*)malloc(k * sizeof(int));
// Initialize the heap with the first k elements
for (int i = 0; i < k; i++)
heap[i] = nums[i];
// Build the min-heap
buildMinHeap(heap, k);
// Process the remaining elements of the array
for (int i = k; i < numsSize; i++)
// If the current element is larger than the root
of the heap
if (nums[i] > heap[0]) {
// Replace the root with the current element
heap[0] = nums[i];
// Heapify the root to maintain the min-heap
property
heapify(heap, k, 0);
}
// The root of the heap is the kth largest element
int kthLargest = heap[0];
// Free the allocated memory for the heap
free(heap);
// Return the kth largest element
return kthLargest;
}
int main() {
int numsSize;
int k;
// Read the size of the array from the user
printf("Enter the number of elements: ");
scanf("%d", &numsSize);
// Allocate memory for the array
int* nums = (int*)malloc(numsSize * sizeof(int));
// Read the elements of the array from the user
printf("Enter the elements of the array: ");
for (int i = 0; i < numsSize; i++)
scanf("%d", &nums[i]);
// Read the value of k from the user
printf("Enter the value of k: ");
scanf("%d", &k);
// Find and print the kth largest element
int result = findKthLargest(nums, numsSize, k);
printf("The %dth largest element is %d\n", k, result);
// Free the allocated memory for the array
free(nums);
return 0;
}
518. Coin Change II
You are given an integer array coins representing coins
of different denominations and an integer amount
representing a total amount of money.
Return the number of combinations that make up that
amount. If that amount of money cannot be made up by any
combination of the coins, return 0.
You may assume that you have an infinite number of each
kind of coin.
The answer is guaranteed to fit into a signed 32-bit
integer.
Example 1:
Input: amount = 5, coins = [1,2,5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
Example 2:
Input: amount = 3, coins = [2]
Output: 0
Explanation: the amount of 3 cannot be made up just with
coins of 2.
Example 3:
Input: amount = 10, coins = [10]
Output: 1
Constraints:
1 <= coins.length <= 300
1 <= coins[i] <= 5000
All the values of coins are unique.
0 <= amount <= 5000
Solution
#include <stdio.h>
#include <stdlib.h>
int change(int amount, int* coins, int coinsSize) {
// Allocate and initialize the dp array
int* dp = (int*)calloc(amount + 1, sizeof(int));
dp[0] = 1; // There's one way to make amount 0, which
is to use no coins
// Fill the dp array
for (int i = 0; i < coinsSize; i++)
for (int j = coins[i]; j <= amount; j++)
dp[j] += dp[j - coins[i]];
int result = dp[amount];
free(dp); // Free the allocated memory
return result;
}
int main() {
int amount;
int coinsSize;
// Read the amount
printf("Enter the amount: ");
scanf("%d", &amount);
// Read the number of coins
printf("Enter the number of different coins: ");
scanf("%d", &coinsSize);
// Allocate memory for the coins array
int* coins = (int*)malloc(coinsSize * sizeof(int));
// Read the coin denominations
printf("Enter the coin denominations: ");
for (int i = 0; i < coinsSize; i++)
scanf("%d", &coins[i]);
// Find and print the number of combinations
int result = change(amount, coins, coinsSize);
printf("The number of combinations to make up the
amount %d is %d\n", amount, result);
// Free the allocated memory
free(coins);
return 0;
}
1365. How Many Numbers Are Smaller
Than the Current Number
Given the array nums, for each nums[i] find out how many
numbers in the array are smaller than it. That is, for
each nums[i] you have to count the number of valid j's
such that j != i and nums[j] < nums[i].
Return the answer in an array.
Example 1:
Input: nums = [8,1,2,2,3]
Output: [4,0,1,1,3]
Explanation:
For nums[0]=8 there exist four smaller numbers than it (1,
2, 2 and 3).
For nums[1]=1 does not exist any smaller number than it.
For nums[2]=2 there exist one smaller number than it (1).
For nums[3]=2 there exist one smaller number than it (1).
For nums[4]=3 there exist three smaller numbers than it
(1, 2 and 2).
Example 2:
Input: nums = [6,5,4,8]
Output: [2,1,0,3]
Example 3:
Input: nums = [7,7,7,7]
Output: [0,0,0,0]
Constraints:
2 <= nums.length <= 500
0 <= nums[i] <= 100
Solution
#include <stdio.h>
#include <stdlib.h>
int* smallerNumbersThanCurrent(int* nums, int numsSize,
int* returnSize) {
// Allocate memory for the result array
*returnSize = numsSize;
int* result = (int*)malloc(numsSize * sizeof(int));
// Frequency array to count occurrences of each
number in nums
int count[101] = {0};
// Count each number in the nums array
for (int i = 0; i < numsSize; i++)
count[nums[i]]++;
// Accumulate the counts to find how many numbers are
smaller than each number
int smallerCount[101] = {0};
for (int i = 1; i < 101; i++)
smallerCount[i] = smallerCount[i - 1] + count[i -
1];
// Fill the result array using the accumulated counts
for (int i = 0; i < numsSize; i++)
result[i] = smallerCount[nums[i]];
return result;
}
int main() {
int numsSize;
int *nums;
int returnSize;
// Read the size of the array
printf("Enter the number of elements in the array: ");
scanf("%d", &numsSize);
// Allocate memory for the array
nums = (int*)malloc(numsSize * sizeof(int));
// Read the elements of the array
printf("Enter the elements of the array: ");
for (int i = 0; i < numsSize; i++)
scanf("%d", &nums[i]);
// Find the result array
int* result = smallerNumbersThanCurrent(nums,
numsSize, &returnSize);
// Print the result array
printf("Output: ");
for (int i = 0; i < returnSize; i++) {
printf("%d", result[i]);
if (i < returnSize - 1)
printf(", ");
}
printf("\n");
// Free the allocated memory
free(nums);
free(result);
return 0;
}
1450. Number of Students Doing
Homework at a Given Time
Given two integer arrays startTime and endTime and given
an integer queryTime.
The ith student started doing their homework at the time
startTime[i] and finished it at time endTime[i].
Return the number of students doing their homework at
time queryTime. More formally, return the number of
students where queryTime lays in the interval
[startTime[i], endTime[i]] inclusive.
Example 1:
Input: startTime = [1,2,3], endTime = [3,2,7], queryTime
= 4
Output: 1
Explanation: We have 3 students where:
The first student started doing homework at time 1 and
finished at time 3 and wasn't doing anything at time 4.
The second student started doing homework at time 2 and
finished at time 2 and also wasn't doing anything at time
4.
The third student started doing homework at time 3 and
finished at time 7 and was the only student doing
homework at time 4.
Example 2:
Input: startTime = [4], endTime = [4], queryTime = 4
Output: 1
Explanation: The only student was doing their homework at
the queryTime.
Constraints:
startTime.length == endTime.length
1 <= startTime.length <= 100
1 <= startTime[i] <= endTime[i] <= 1000
1 <= queryTime <= 1000
Solution
#include <stdio.h>
#include <stdlib.h>
// Function to count the number of students doing
homework at queryTime
int busyStudent(int* startTime, int startTimeSize, int*
endTime, int endTimeSize, int queryTime) {
int count = 0;
for (int i = 0; i < startTimeSize; i++)
if (startTime[i] <= queryTime && endTime[i] >=
queryTime)
count++;
return count;
}
int main() {
int n, queryTime;
// Read the size of the arrays
printf("Enter the number of students: ");
scanf("%d", &n);
// Allocate memory for startTime and endTime arrays
int* startTime = (int*)malloc(n * sizeof(int));
int* endTime = (int*)malloc(n * sizeof(int));
// Read the elements of the startTime array
printf("Enter the start times: ");
for (int i = 0; i < n; i++)
scanf("%d", &startTime[i]);
// Read the elements of the endTime array
printf("Enter the end times: ");
for (int i = 0; i < n; i++)
scanf("%d", &endTime[i]);
// Read the query time
printf("Enter the query time: ");
scanf("%d", &queryTime);
// Find and print the number of students doing
homework at queryTime
int result = busyStudent(startTime, n, endTime, n,
queryTime);
printf("Number of students doing homework at
time %d: %d\n", queryTime, result);
// Free the allocated memory
free(startTime);
free(endTime);
return 0;
}