This is a hackerrank problem.
Find out the maximum movies that can be watched. Assume the list to be distinct movies.
Input:
movieStart[] = {10,12,9,14,16,14}
movieEnd[] = {11,13,15,16,18,18}
Output : 4 (10-11,12-13,14-16,16-18)
Below code is giving me correct output. Would like to know the best solution possible for this problem.
Also what algorithm is used to solve this kind of problem?
static int getMaxMovies(int[] movie_start, int[] movie_end) {
int cnt = 0;
for (int i = 0; i < movie_start.length; i++) {
for (int j = 0; j < movie_start.length; j++) {
if (movie_start[j] == movie_start[i] && movie_end[j] == movie_end[i]) {
continue;
}
if (movie_start[j] >= movie_start[i] && movie_end[j] <= movie_end[i]) {
cnt += 1;
break;
}
}
}
return movie_start.length - cnt;
}
That's "Activity selection" problem - which could be easily solved with O(n) (in case of sorted input) or O(nlogn) (when input isn't sorted) greedy algorithm. If input is already sorted by finishing (end) time you should pick movies which doesn't conflict with previously selected movie.
Pseudocode:
Sort by finish times
int previouslySelectedIndex = 0;
int watchedMoviesCount = 1;
for (int i=1; i<movie_end.Length; i++)
{
if (movie_start[i] >= movie_end[previouslySelectedIndex)
{
watchedMoviesCount++;
previouslySelectedIndex=i;
}
}
Related
This is a classic question, where a list of coin amounts are given in coins[], len = length of coins[] array, and we try to find minimum amount of coins needed to get the target.
The coins array is sorted in ascending order
NOTE: I am trying to optimize the efficiency. Obviously I can run a for loop through the coins array and add the target%coins[i] together, but this will be erroneous when I have for example coins[] = {1,3,4} and target = 6, the for loop method would give 3, which is 1,1,4, but the optimal solution is 2, which is 3,3.
I haven't learned matrices and multi-dimensional array yet, are there ways to do this problem without them? I wrote a function, but it seems to be running in an infinity loop.
int find_min(const int coins[], int len, int target) {
int i;
int min = target;
int curr;
for (i = 0; i < len; i++) {
if (target == 0) {
return 0;
}
if (coins[i] <= target) {
curr = 1 + find_min(coins, len, target - coins[i]);
if (curr < min) {
min = curr;
}
}
}
return min;
}
I can suggest you this reading,
https://www.geeksforgeeks.org/generate-a-combination-of-minimum-coins-that-results-to-a-given-value/
the only thing is that there is no C version of the code, but if really need it you can do the porting by yourself.
Since no one gives a good answer, and that I figured it out myself. I might as well post an answer.
I add an array called lp, which is initialized in main,
int lp[4096];
int i;
for (i = 0; i <= COINS_MAX_TARGET; i++) {
lp[i] = -1;
}
every index of lp is equal to -1.
int find_min(int tar, const int coins[], int len, int lp[])
{
// Base case
if (tar == 0) {
lp[0] = 0;
return 0;
}
if (lp[tar] != -1) {
return lp[tar];
}
// Initialize result
int result = COINS_MAX_TARGET;
// Try every coin that is smaller than tar
for (int i = 0; i < len; i++) {
if (coins[i] <= tar) {
int x = find_min(tar - coins[i], coins, len, lp);
if (x != COINS_MAX_TARGET)
result = ((result > (1 + x)) ? (1+x) : result);
}
}
lp[tar] = result;
return result;
}
I am learning algorithms as a beginner.When learning quicksort,I found that there're several ways to implement the quick sort.So I choose this the way in this tutorial to implement quicksort.
It chooses the element in end of the array as pivot,and choose the first element as a wall separating the values which are less and greater than the pivot.when the sort is done, insert the pivot in the position of wall and make partition.
Here's my implementation in c:
void simpleqs(int* data,int start,int end)
{
int wall = start;
int pivot = data[end];
//Base case
if (start >= end)
{
return;
}
//Sort the array
for(int e = start;e < end-1; e++)
{
if(data[e] < pivot)
{
swap(&data[e],&data[wall]);
wall++;
}
}
//Partition
if(data[wall] >= pivot)
{
swap(&data[wall],&data[end]);
}
simpleqs(data,start,wall-1);
simpleqs(data,wall+1,end);
}
In main:
int main(void)
{
int dataSet[] = {2,4,1,5,6,9,8,3,7,10,20,13,11,17,15};
int size = sizeof(dataSet)/sizeof(int);
simpleqs(dataSet,0,size-1);
for(int e = 0;e < size ; e++)
{
printf("%d,", dataSet[e]);
}
printf("\n");
}
There will always be one value in the wrong position,I can't figure out why.
Like this:
1,2,3,4,5,6,8,9,7,10,11,13,15,17,20,
Please help me to revise my logic,thanks!
You should go to the end, not end - 1.
// Sort the array
for (int e = start; e < end; e++)
{
if (data[e] < pivot)
{
swap(&data[e], &data[wall]);
wall++;
}
}
You have implemented Lomuto partition, but missed treatment of (end-1)-th element:
for(int e = start;e < end; e++)
I completed my Problem Set 3 helpers.c program and it works perfectly up to a total of 10 of haystack but stops working when I press Control-D with less than 10 in haystack. Instead the program skips a line and I can freely write like in a not pad. Since, it can not pass 3 or 4 in haystacks, my program can't pass Check50. Does anybody have a solution to this problem?
In case you need my code, here it is:
bool search(int value, int values[], int n)
{
if(value < 0)
{
return false;
}
for(int i = 0; i < n; i++)
{
if (value == values[i])
{
return true;
}
}
return false;
}
/**
* Sorts array of n values.
*/
void sort(int values[], int n)
{
bool tf;
do
{
tf = false;
for(int i=0; i < n-1; i++)
{
if(values[i] > values[i+1])
{
int temp = values[i];
values[i] = values[i+1];
values[i+1] = temp;
tf = true;
}
}
}
while(tf == false);
return;
}
Your sorting algorithm is flawed. It just takes one round of the whole array and arranges it partially in order but not fully.
You can use bubble sort (refer to https://en.wikipedia.org/wiki/Bubble_sort or the lecture of cs50) of which I cannot provide code as it is against the honour code of the course.
I am given 2 arrays, Input and Output Array. The goal is to transform the input array to output array by performing shifting of 1 value in a given step to its adjacent element. Eg: Input array is [0,0,8,0,0] and Output array is [2,0,4,0,2]. Here 1st step would be [0,1,7,0,0] and 2nd step would be [0,1,6,1,0] and so on.
What can be the algorithm to do this efficiently? I was thinking of performing BFS but then we have to do BFS from each element and this can be exponential. Can anyone suggest solution for this problem?
I think you can do this simply by scanning in each direction tracking the cumulative value (in that direction) in the current array and the desired output array and pushing values along ahead of you as necessary:
scan from the left looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the right
scan from the right looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the left
For your example the steps would be:
FWD:
[0,0,8,0,0]
[0,0,7,1,0]
[0,0,6,2,0]
[0,0,6,1,1]
[0,0,6,0,2]
REV:
[0,1,5,0,2]
[0,2,4,0,2]
[1,1,4,0,2]
[2,0,4,0,2]
i think BFS could actually work.
notice that n*O(n+m) = O(n^2+nm) and therefore not exponential.
also you could use: Floyd-Warshall algorithm and Johnson’s algorithm, with a weight of 1 for a "flat" graph, or even connect the vertices in a new way by their actual distance and potentially save some iterations.
hope it helped :)
void transform(int[] in, int[] out, int size)
{
int[] state = in.clone();
report(state);
while (true)
{
int minPressure = 0;
int indexOfMinPressure = 0;
int maxPressure = 0;
int indexOfMaxPressure = 0;
int pressureSum = 0;
for (int index = 0; index < size - 1; ++index)
{
int lhsDiff = state[index] - out[index];
int rhsDiff = state[index + 1] - out[index + 1];
int pressure = lhsDiff - rhsDiff;
if (pressure < minPressure)
{
minPressure = pressure;
indexOfMinPressure = index;
}
if (pressure > maxPressure)
{
maxPressure = pressure;
indexOfMaxPressure = index;
}
pressureSum += pressure;
}
if (minPressure == 0 && maxPressure == 0)
{
break;
}
boolean shiftLeft;
if (Math.abs(minPressure) > Math.abs(maxPressure))
{
shiftLeft = true;
}
else if (Math.abs(minPressure) < Math.abs(maxPressure))
{
shiftLeft = false;
}
else
{
shiftLeft = (pressureSum < 0);
}
if (shiftLeft)
{
++state[indexOfMinPressure];
--state[indexOfMinPressure + 1];
}
else
{
--state[indexOfMaxPressure];
++state[indexOfMaxPressure + 1];
}
report(state);
}
}
A simple greedy algorithm will work and do the job in minimum number of steps. The function returns the total numbers of steps required for the task.
int shift(std::vector<int>& a,std::vector<int>& b){
int n = a.size();
int sum1=0,sum2=0;
for (int i = 0; i < n; ++i){
sum1+=a[i];
sum2+=b[i];
}
if (sum1!=sum2)
{
return -1;
}
int operations=0;
int j=0;
for (int i = 0; i < n;)
{
if (a[i]<b[i])
{
while(j<n and a[j]==0){
j++;
}
if(a[j]<b[i]-a[i]){
operations+=(j-i)*a[j];
a[i]+=a[j];
a[j]=0;
}else{
operations+=(j-i)*(b[i]-a[i]);
a[j]-=(b[i]-a[i]);
a[i]=b[i];
}
}else if (a[i]>b[i])
{
a[i+1]+=(a[i]-b[i]);
operations+=(a[i]-b[i]);
a[i]=b[i];
}else{
i++;
}
}
return operations;
}
Here -1 is a special value meaning that given array cannot be converted to desired one.
Time Complexity: O(n).
I have been learning C for like a week now. Today I have learned arrays and how to sort them using bubble sort, so I have written some code according to the book, it works great alone, but it won't work with a bigger program, the loops will just be skipped. I have tried to debug it, it works great until line 20 when for some reason outer will immediatly equal 9 and so inner will equal 10 and the program will move on. Here is my code :
#include <stdio.h>
int main(void) {
int ctr; //loop counter
int idSearch; //Customer to look for (the key)
int found = 0; // 1 (true) if the customer is found
/* Defines the 10 elements in each of the parallel arrays */
int custID[10] = {313, 454, 502, 101, 892, 475, 792, 912, 343, 644};
float custBal[10] = {0.00, 45.43, 71.23, 301.56, 9.08, 192.41, 389.00, 229.67,
18.31, 59.54};
int tempID, inner, outer; // For sorting float temBal
tempID = inner = outer = 0;
float tempBal =0;
/* first, sort the arrays by customer ID */
for (outer=0; outer < 9; outer++);
{
for (inner = (outer+1); inner < 10; inner++)
{
if (custID[inner] < custID[outer])
{
tempID = custID[inner]; // must switch both arrays
tempBal = custBal[inner]; // or they won't be linked
custID[inner] = custID[outer];
custBal[inner] = custBal[outer];
custID[outer] = tempID;
custBal[outer] = tempBal;
}
}
}
/* Interact with the user looking to find a balance */
printf("**Customer Balance Lookup**\n");
printf("What is the customer's number? ");
scanf(" %d", &idSearch);
/* Now look for the ID in the array */
for (ctr = 0; ctr <10; ctr++)
{
if (idSearch == custID[ctr]) //Do they match?
{
found = 1; // Yes, match flag is set to True
break;
}
if (custID[ctr] > idSearch) // No need to keep searching
{
break;
}
}
// Once the loop has completed, the ID was either found if not
if (found)
{
if (custBal[ctr] > 100)
{
printf("\n**That customer's balance is $%.2f.**\n", custBal[ctr]);
printf("No additional credit\n");
} else {
printf("\n**The customer's balance is good!**");
}
}else { printf("\n**You have entered an incorrect customer ID.**");
printf("\n ID %d was not found in the list.\n", idSearch);
}
return (0);
}
It appears that you are trying to bubble sort the custID array, and in the process also sort the custBal array. However, your logic for doing bubble sort is convoluted. Try using this double for loop instead:
for (outer = 0; outer < ( n - 1 ); outer++) {
for (d=inner = 0; inner < n - outer - 1; inner++) {
if (custID[inner] > custID[inner+1])
{
tempID = custID[inner];
tempBal = custBal[inner];
custID[inner] = custID[inner+1];
custBal[inner] = custBal[inner+1];
custID[inner+1] = tempID;
custBal[inner+1] = tempBal;
}
}
}
I am really embarrassed to write this, but after 30 mins of looking through my code, going through it line by line, I found a semi colon at the end of line 20 for (outer=0; outer < 9; outer++);
Thank you guys for trying to help me I really appreciate it.