QN;Here is the question.i dont know where my algorithm is wrong.help me find pls
Given an array A of N length. We need to calculate the next greater element for each element in given array. If next greater element is not available in given array then we need to fill ‘_’ at that index place.
Input:
The first line contains an integer T, the number of test cases. For each test case, the first line contains an integer n, the size of the array. Next line contains n space separated integers denoting the elements of the array.
Output:
For each test case, the output is an array that displays next greater element to element at that index.
Constraints:
1 <= T <= 100
1 <= N <= 100
-106 <= Ai <= 106
Example:
Input
2
9
6 3 9 8 10 2 1 15 7
4
13 6 7 12
Output:
7 6 10 9 15 3 2 _ 8
_ 7 12 13
Explanation:
Testcase 1: Here every element of the array has next greater element but at index 7, 15 is the greatest element of given array and no other element is greater from 15 so at the index of 15 we fill with ''.
Testcase 2: Here, at index 0, 13 is the greatest value in given array and no other array element is greater from 13 so at index 0 we fill ''.
My solution:
//NOT SOLVED YET
#include<iostream>
using namespace std;
int main()
{
int a[10]={6 ,3 ,9, 8 ,10, 2 ,1, 15, 7};
int b[10],flag=0,big=-1,i,j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
if(i==j)continue;
if((a[j]>a[i]) && (flag==0))
{
big=a[j];
flag=1;
}
else if(a[j]<big && big>a[i] && flag==1)
big=a[j];
}
if(big==-1)cout<<'_';
else cout<<big<<' ';
big=-1;
flag=0;
}
}
the output i get is:
2 2 2 2 7 1 0 _ 2 1
The condition should be:
else if(a[j] < big && a[j] > a[i] && flag == 1)
Indeed, if you use big > a[i], then that means you just check if the thus far next greater element was larger than a[i], but this thus makes it possible to select a value later in the process that is smaller than big, but smaller than a[i] as well. Here we thus want to check if a[j] is between a[i] and big.
That being said, the above approach is not very efficient. Indeed, for each element, you calculate the next element in linear time, making this a quadratic time algorithm. You might want to look at solutions where the list is sorted first. You can for example use min-heap here to move over the list in two passes.
To expand on what others have mentioned - that you currently have an O(N^2) algorithm, and this can be done more efficiently.
I don't think you can get O(N) here, but here is a plan for an O(N log N) algorithm:
For each test case:
Load the Ai values into two arrays, let's call them X and Y
Sort the Y array
Iterate over X and for each element of X do a binary search into Y to find the next larger value of Ai: use that as the output, or use _ if you did not find one
I recommend, for practice purposes, implementing this both using the C++ standard library, using https://en.cppreference.com/w/cpp/algorithm/sort and https://en.cppreference.com/w/cpp/algorithm/upper_bound , and implementing the above two functions yourself, see: https://en.wikipedia.org/wiki/Quicksort
Related
Working on a business class assignment where we're using Excel to solve a problem with the following setup and conditions, but I wanted to find solutions by writing some code in C++ which is what I'm most familiar from some school courses.
We have 4 stores where we need to invest 10 million dollars. The main conditions are:
It is necessary to invest at least 1mil per store.
The investments in the 4 stores must total 10 million.
Following the rules above, the most one can invest in a single store is 7 million
Each store has its own unique return of investment percentages based off the amount of money invested per store.
In other words, there is a large number of combinations that can be obtained by investing in each store. Repetition of numbers does not matter as long as the total is 10 per combination, but the order of the numbers does matter.
If my math is right, the total number of combinations is 7^4 = 2401, but the number of working solutions
is lesser due to the condition that each combination must equal 10 as a sum.
What I'm trying to do in C++ is use loops to populate each row with 4 numbers such that their sum equals 10 (millions), for example:
7 1 1 1
1 7 1 1
1 1 7 1
1 1 1 7
6 2 1 1
6 1 2 1
6 1 1 2
5 3 1 1
5 1 3 1
5 1 1 3
5 1 2 2
5 2 1 2
5 2 2 1
I'd appreciate advice on how to tackle this. Still not quite sure if using loops is a good idea whilst using an array (2D Array/Vector perhaps?) I've a vague idea that maybe recursive functions would facilitate a solution.
Thanks for taking some time to read, I appreciate any and all advice for coming up with solutions.
Edit:
Here's some code I worked on to just get 50 rows of numbers randomized. Still have to implement the conditions where valid row combinations must be the sum total of 10 between the 4;
int main(){
const int rows = 50;
int values[rows][4];
for (int i = 0; i < 50; i++) {
for (int j = 0; j <= 3; j++){
values[i][j]= (rand() % 7 + 1);
cout << values[i][j] << " ";
}
cout << endl;
}
}
You can calculate this recursively. For each level, you have:
A target sum
The number of elements in that level
The minimum value each individual element can have
First, we determine our return type. What's your final output? Looks like a vector of vectors to me. So our recursive function will return a the same.
Second, we determine the result of our degenerate case (at the "bottom" of the recursion), when the number of elements in this level is 1.
std::vector<std::vector<std::size_t>> recursive_combinations(std::size_t sum, std::size_t min_val, std::size_t num_elements)
{
std::vector<std::vector<std::size_t>> result {};
if (num_elements == 1)
{
result.push_back(std::vector<std::size_t>{sum});
return result;
}
...non-degenerate case goes here...
return result;
}
Next, we determine what happens when this level has more than 1 element in it. Split the sum into all possible pairs of the "first" element and the "remaining" group. e.g., if we have a target sum of 5, 3 num_elements, and a min_val of 1, we'd generate the pairs {1,4}, {2,3}, and {3,2}, where the first number in each pair is for the first element, and the second number in each pair is the remaining sum left over for the remaining group.
Recursively call the recursive_combinations function using this second number as the new sum, and num_elements - 1 as the new num_elements to find the vector of vectors for the remaining group, and for each vector in the return vector, append the first element from the above set.
question:
Given an array of elements of length N, ranging from 0 to N-1, your task is to write a program that rearranges the elements of the array. All elements may not be present in the array, if element is not present then there will be -1 present in the array. Rearrange the array such that A[i] = i and if i is not present, display -1 at that place.
my code:
#include <iostream>
using namespace std;
int main()
{
long int n;
cin>>n;
long int a[n];
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for (int i=1;i<=n;i++)
{
while(a[i]==i&&a[i]==-1)
{
int temp=a[i];
a[i]=a[temp];
a[temp]=temp;
}
}
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 1;
}
output:
6
-1 4 2 3 -1 5
-1 4 2 3 -1 5
can anyone please help me in finding out my error in the logic apllied?
Thanks in advance.
for(int i=1;i<=n;i++)
Wrong, elements go from 0 to N-1, not 1 to N
while(a[i]==i&&a[i]==-1)
This will never happen, you are asking for a[i] to be equal to both i and -1, which means asking i to be equal to -1, which won´t happen in your loop.
For a simple answer, you need to sort the list and then process that. For an efficient answer, you will want to make a boolean array of size N and then iterate the array and check which values are present. Then you iterate the boolean array to write the number when it is present or -1 when its not.
The easiest way to solve this kind of problem is to get a pack of playing cards and lay them out on your desk, and then solve the problem by hand. Write down every step you take, and then write code that performs those steps.
Because cards start at 1, rather than 0, I use the 10 as a 0. Use the joker to indicate an empty space (-1 in your problem description).
Take five cards and lay them out in six spaces
2 10 4 J 3 1
Starting with position 0. Pull the 2 out and replace it with -1, so your cards look like this:
J 10 4 J 3 1
And you're holding the 2 in your hand.
Then, go to position 2, pull out the 4 and put the 2 there. Now you have
J 10 2 J 3 1
And you're holding 4 in your hand. Go to position 4 (where the 3 is). Replace the 3 with 4, you have:
J 10 2 J 4 1
And 3 in the hand. Position 3 contains a joker. So you put the 3 in that position and put the joker aside. You now have:
J 10 2 3 4 1
So you move to the next position, 1. Pick up the 10 and put a joker in that spot. The 10 goes to position 0, so take the joker from position 0, place the 10 there, and you have:
10 J 2 3 4 1
You don't have anything in your hand now, so you move forward, checking positions 2, 3, and 4, which already have a[i] == i. But position 5 contains a 1. So you pick it up, place a joker in that position, and then replacing the joker in position 1 with the value 1 that you just pulled from position 5. Your array now looks like this:
10 1 2 3 4 J
And you're done.
Do that a few times with different arrangements of cards, writing down the steps you took. After a few practice runs, you should be able to write down the general algorithm for solving the problem. Then you write a program to implement that solution.
The idea of this kind of problem is to help you develop these problem solving steps. Over time, you'll be able to go straight to code with the simpler problems, but you'll find that building a physical model is very useful with more complex problems. If you step away from the computer, you're not tempted to start programming before you've solved the problem. You'll find that doing things way will save you a lot of frustration.
A list partially ordered of n numbers is given and I have to find those numbers that does not follow the order (just find them and count them).
There are no repeated numbers.
There are no negative numbers.
MAX = 100000 is the capacity of the list.
n, the number of elements in the list, is given by the user.
Example of two lists:
1 2 5 6 3
1 6 2 9 7 4 8 10 13
For the first list the output is 2 since 5 and 6 should be both after 3, they are unordered; for the second the output is 3 since 6, 9 and 7 are out of order.
The most important condition in this problem: do the searching in a linear way O(n) or being quadratic the worst case.
Here is part of the code I developed (however it is no valid since it is a quadratic search).
"unordered" function compares each element of the array with the one given by "minimal" function; if it finds one bigger than the minimal, that element is unordered.
int unordered (int A[MAX], int n)
int cont = 0;
for (int i = 0; i < n-1; i++){
if (A[i] > minimal(A, n, i+1)){
count++;
}
}
return count;
"minimal" function takes the minimal of all the elements in the list between the one which is being compared in "unordered" function and the last of the list. i < elements <= n . Then, it is returned to be compared.
int minimal (int A[MAX], int n, int index)
int i, minimal = 99999999;
for (i = index; i < n; i++){
if (A[i] <= minimo)
minimal = A[i];
}
return minimal;
How can I do it more efficiently?
Start on the left of the list and compare the current number you see with the next one. Whenever the next is smaller than the current remove the current number from the list and count one up. After removing a number at index 'n' set your current number to index 'n-1' and go on.
Because you remove at most 'n' numbers from the list and compare the remaining in order, this Algorithmus in O(n).
I hope this helps. I must admit though that the task of finding numbers that are out of of order isn't all that clear.
If O(n) space is no problem, you can first do a linear run (backwards) over the array and save the minimal value so far in another array. Instead of calling minimal you can then look up the minimum value in O(1) and your approach works in O(n).
Something like this:
int min[MAX]; //or: int *min = new int[n];
min[n-1] = A[n-1];
for(int i = n-2; i >= 0; --i)
min[i] = min(A[i], min[i+1]);
Can be done in O(1) space if you do the first loop backwards because then you only need to remember the current minimum.
Others have suggested some great answers, but I have an extra way you can think of this problem. Using a stack.
Here's how it helps: Push the leftmost element in the array onto the stack. Keep doing this until the element you are currently at (on the array) is less than top of the stack. While it is, pop elements and increment your counter. Stop when it is greater than top of the stack and push it in. In the end, when all array elements are processed you'll get the count of those that are out of order.
Sample run: 1 5 6 3 7 4 10
Step 1: Stack => 1
Step 2: Stack => 1 5
Step 3: Stack => 1 5 6
Step 4: Now we see 3 is in. While 3 is less than top of stack, pop and increment counter. We get: Stack=> 1 3 -- Count = 2
Step 5: Stack => 1 3 7
Step 6: We got 4 now. Repeat same logic. We get: Stack => 1 3 4 -- Count = 3
Step 7: Stack => 1 3 4 10 -- Count = 3. And we're done.
This should be O(N) for time and space. Correct me if I'm wrong.
I have implemented a quick sort algorithm but when I tested it I noticed that it fails when the input array has the largest element in the first element (this is the element I got the pivot from). Here's my code:
void partition(int *a,int size){
if(size<=1){return;}
int pivot=a[0];
int left=0,right=0;
for(left=1,right=size-1;left<=right;){ //was size-1
if(a[left]>=pivot&&a[right]<=pivot) {
swap(left,right,a);
}
if(a[left]<pivot){left++;}
if(a[right]>pivot){right--;}
}
swap(0,right,a);
partition(a,right-1);
partition(&(a[right+1]),size-right-1);
}
Some samples that it fails on:
I/P 245 111 32 4
O/P 4 111 32 245 `
I/P 154 11 43 3 7
O/P 7 11 43 3 154
What are the possible mistakes I have made?
Well, the problem lies here :
partition(a,right-1); // <- It's partition(array,size)!
Change it to
partition(a,right);
And it will work. I think you know the reason.
For the partition function to work correctly, you must supply 2 things :
1) The array to work on.
2) The number of elements it has, the size.
The problem lies in the first recursive call to partition the left subarray: partition(a,right-1)
The argument 2, the size, is incorrectly specified to be right-1, when it is actually right.
This can be worked out by using the fact that the number of elements in an array from an index a to b ( both included,b>=a) are N= b-a+1.
Here, we have a=0, b=right-1, thus the number of elements in the left sub array, the size, N=(right-1)-(0)+1=right.
Thus the to work correctly, you must call it like partition(a,right);.
The left sub array ends at right-1, but it has right-1+1=right elements.
Happens all the time :)
You are missing a case where there is an element in the array which is the pivot, in the partition function.
Assume arr = { 5, 5, 1 , 1, 5, }
pivot = 5
iter1:
left=1, arr[left]=5 ; right=4,arr[right]=5
(swapping)
not increasing left nor decreasing right - since 5 < 5 == false ; 5 > 5 == false
Next iteration, the same scenario will repeat itself, and you will actually get an infinite loop.
One way to deal with it is to determine that the "big" part will also increase all elements that are exactly the pivot, and swap elements if arr[right] < pivot (not <=), and decrease right if arr[right] >= pivot (not >), something like:
...
for(left=1,right=size-1;left<=right;){ //was size-1
if(a[left]>=pivot&&a[right]<pivot) {
// ^ note < not <=
swap(left,right,a);
}
if(a[left]<pivot){left++;}
if(a[right]>=pivot){right--;}
// ^ note >=
}
...
I am having a Algorithm question, in which numbers are been given from 1 to N and a number of operations are to be performed and then min/max has to be found among them.
Two operations - Addition and subtraction
and operations are in the form a b c d , where a is the operation to be performed,b is the starting number and c is the ending number and d is the number to be added/subtracted
for example
suppose numbers are 1 to N
and
N =5
1 2 3 4 5
We perform operations as
1 2 4 5
2 1 3 4
1 4 5 6
By these operations we will have numbers from 1 to N as
1 7 8 9 5
-3 3 4 9 5
-3 3 4 15 11
So the maximum is 15 and min is -3
My Approach:
I have taken the lower limit and upper limit of the numbers in this case it is 1 and 5 only stored in an array and applied the operations, and then had found the minimum and maximum.
Could there be any better approach?
I will assume that all update (addition/subtraction) operations happen before finding max/min. I don't have a good solution for update and min/max operations mixing together.
You can use a plain array, where the value at index i of the array is the difference between the index i and index (i - 1) of the original array. This makes the sum from index 0 to index i of our array to be the value at index i of the original array.
Subtraction is addition with the negated number, so they can be treated similarly. When we need to add k to the original array from index i to index j, we will add k to index i of our array, and subtract k to index (j + 1) of our array. This takes O(1) time per update.
You can find the min/max of the original array by accumulating summing the values and record the max/min values. This takes O(n) time per operation. I assume this is done once for the whole array.
Pseudocode:
a[N] // Original array
d[N] // Difference array
// Initialization
d[0] = a[0]
for (i = 1 to N-1)
d[i] = a[i] - a[i - 1]
// Addition (subtraction is similar)
add(from_idx, to_idx, amount) {
d[from_idx] += amount
d[to_idx + 1] -= amount
}
// Find max/min for the WHOLE array after add/subtract
current = max = min = d[0];
for (i = 1 to N - 1) {
current += d[i]; // Sum from d[0] to d[i] is a[i]
max = MAX(max, current);
min = MIN(min, current);
}
Generally there is no "best way" to find the min/max in the performance point of view because it depends on how this application will be used.
-Finding the max and min in a list needs O(n) Time, so if you want to run many (many in the context of the input) operations, your approach to find the min/max after all the operations took place is fine.
-But if the list will hold many elements and you don’t want to run that many operations, you better check each result of the op if its a new max/min and update if necessary.