I successfully solved a question on Hackerrank, and it passed all test cases but I got an error Time Limit Exceeded. I'm guessing if I optimize my code it would work,but I can't think of any way to make my code more efficient.
The question is:
A left rotation operation on an array of size n shifts each of the array's elements 1 unit to the left. For example, if 2 left rotations are performed on array [1,2,3,4,5], then the array would become [3,4,5,1,2].
Given an array of n integers and a number, d, perform d left rotations on the array. Then print the updated array as a single line of space-separated integers.
Can any one please guide me on how to make this code more efficient?
My code is:
vector<int> array_left_rotation(vector<int> a, int n, int k) {
for (int j = 0; j < k; j++){
a[n] = a[0];
for (int i = 0; i < n; i++){
a[i] = a[i+1];
}
a[n-1] = a[n];
}
return a;
}
n is the number of elements in the array
k is the number of rotations to be performed
You don't need to actually rotate the array for this problem. The formula (i + k) % n will give you the element at index i in an array that has been rotated k times to the left. Knowing this you can pass through the array once accessing each element in this manner:
int main() {
int* arr, n, k, i;
cin >> n >> k;
arr = new int[n];
for (i = 0; i < n; ++i)
cin >> arr[i];
for (i = 0; i < n; ++i)
cout << arr[(i + k) % n] << " ";
}
Instead of performing k rotations, try performing a k-rotation:
Rotate the entire array left by k in one go. That's much more efficient.
If another vector will not cause a space problem, you may just copy them with an offset:
//Not tested
vector<int> array_left_rotation(vector<int> a, int n, int k) {
std::vector<int> result(n);
for (int j = 0; j < k; j++){
result[j]=a[(j+k)%n];
}
return result;
}
using namespace std;
#include<iostream>
int main()
{
int a[1000000],b[1000000];
int n,d;
cin>>n;
cin>>d;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=0,j;i<n;i++)
{
if(i==0)
{
j=n-d;
b[j]=a[i];
}
else if(i==d)
{
j=i-d;
b[j]=a[i];
}
else
{
j=(n-d+i);
if(j>n)
{
j=(i-d);
b[j]=a[i];
}
else
{
j=(n-d+i);
b[j]=a[i];
}
}
}
for(int i=0;i<n;i++)
{
cout<<b[i]<<" ";
}
}
This passes all the test cases. What i actually did is to move each element in array a[i] k times in an another array b[i] as there is no space constraint.
Related
I know how to code with C, however, this is my first time I try to use C++. And the use of VLAs(Variable Length Arrays) is not allowed in C++. So how can I convert this program to use C++ standard containers( for example std::vector) for the same instead of going the C route?
Instead of int arr[n]; in main(), use std::vector<int> arr(n); and what further changes I have to do? Please assist.
Here is my code,
#include<iostream>
using namespace std;
// A function to heapify the array.
void MaxHeapify(int a[], int i, int n)
{
int j, temp;
temp = a[i];
j = 2*i;
while (j <= n)
{
if (j < n && a[j+1] > a[j])
j = j+1;
// Break if parent value is already greater than child value.
if (temp > a[j])
break;
// Switching value with the parent node if temp < a[j].
else if (temp <= a[j])
{
a[j/2] = a[j];
j = 2*j;
}
}
a[j/2] = temp;
return;
}
void HeapSort(int a[], int n)
{
int i, temp;
for (i = n; i >= 2; i--)
{
// Storing maximum value at the end.
temp = a[i];
a[i] = a[1];
a[1] = temp;
// Building max heap of remaining element.
MaxHeapify(a, 1, i - 1);
}
}
void Build_MaxHeap(int a[], int n)
{
int i;
for(i = n/2; i >= 1; i--)
MaxHeapify(a, i, n);
}
int main()
{
int n, i;
cout<<"\nEnter the number of data element to be sorted: ";
cin>>n;
n++;
int arr[n];
for(i = 1; i < n; i++)
{
cout<<"Enter element "<<i<<": ";
cin>>arr[i];
}
// Building max heap.
Build_MaxHeap(arr, n-1);
HeapSort(arr, n-1);
// Printing the sorted data.
cout<<"\nSorted Data ";
for (i = 1; i < n; i++)
cout<<"->"<<arr[i];
cout<<"\nTime Complexity: Best case = Avg case = Worst case = O(n logn)";
return 0;
}
And the use of VLAs(Variable Length Arrays) is not allowed in C++
I've just compiled your code in C++ and it works perfectly fine. Feel free to rephrase if you think I misunderstood you.
If you want to stick to arrays instead of std::vector you can use std::array. Otherwise in your case it would be mostly swapping int[] for vector<int> with & in function parameters.
This question already has answers here:
Passing a 2D array to a C++ function
(17 answers)
Closed 1 year ago.
I am writing a program to print the sum of the elements of a user entered square matrix in the form of a 2D array without using vector. However I am getting 2 errors:
Error 1: error:array has incomplete element type 'int []'.
Error 2:
error: expected expression cout<<sumarr(arr[][]
This is my program:
int sumarr(int arr[][]) // ERROR 1
{
// finging no. pf rows(or coloums) of the square matrix
int n = sizeof(arr) / (2 * sizeof(int));
int sum = 0;
for (int i = 0; i < n; i++) // calculating sum of elements
{
for (int j = 0; j < n; j++)
{
sum += arr[i][j];
}
}
}
int main()
{
int n; // No. of rows(or coloumns) of the square matrix
cin >> n;
int arr[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++) // inputting array elements
{
cin >> arr[i][j];
}
}
cout << sumarr(arr[][]); // ERROR 2
return 0;
}
Can someone suggest why I am getting these errors and how to resolve them?
In the function parameter (Error 1) you'll need to specify at least the last dimension of the array:
int sumarr(int arr[][SIZE]){ /*...*/}
In the call to the function you need to use the array name only, no dereferencing necessary (Error 2):
cout << sumarr(arr);
The problem then becomes the fact that Variable Length Arrays are not allowed in C++, so you probably should rethink the possibility of using vectors for this task.
Another thing worth mentioning is that sizeof(arr) inside the function will not render you the size of the array but the size of the pointer, which is what arr becomes when passed as an argument.
Alternatively you can manually allocate memory for the array, it could look more or less like this:
Live sample
#include <iostream>
#include <cassert>
// since sizeof arr can't work you should pass the size as argument
int sumarr(int **arr, int n)
{
assert(n > 0 && n < 1000); // confirm that n is valid, > 0 and a suitable upper limit
int sum = 0;
for (int i = 0; i < n; i++) //calculating sum of elements
{
for (int j = 0; j < n; j++)
{
// input and sum in the same loop will save you a O(N^2) operation
std::cin >> arr[i][j];
sum += arr[i][j];
}
}
return sum;
}
int main()
{
int n; //No. of rows(or columns) of the square matrix
std::cin >> n;
// memory allocation for 2D array
int **arr = new int *[n];
for (int i = 0; i < n; i++)
{
arr[i] = new int[n];
}
//end
int sum = sumarr(arr, n); // passing array and size
std::cout << "Sum: " << sum;
// freeing memory after use
for (int i = 0; i < n; i++)
{
delete [] arr[i];
}
delete [] arr;
//end
}
I am trying to implement the following algorithm to find the kth largest number of inputs given in a text file. The first number determines k variable, the next number determines total number of elements (N), and the rest is the number list.
The Algorithm description is:
Store only the first k numbers in an array
Sort the array in decreasing order, e.g., using insertion sort
Read the rest of the numbers one by one:
Ignore if it is smaller than the number at kth position in the array
Otherwise; insert it in its correct position in the array and shift the
remaining numbers (the number at the kth position will be thrown
out of the array)
Return the number at index k-1 in the array.
AlgorithmSortK::AlgorithmSortK(int k) : SelectionAlgorithm(k)
{
this->k = k;
}
int AlgorithmSortK::select()
{
int N = 0;
int x=0;
int *pNums = 0;
cin>>N;
cout<<"N:"<<N<<endl;
pNums = new int[N];
int key, j;
for (int i=0; i<k; i++)
{
cin>>x;
pNums[i] = x;
cout<<pNums[i]<<endl;
for (i = 1; i <k; i++)
{
key = pNums[i];
j = i - 1;
while (j >= 0 && pNums[j] <key)
{
pNums[j + 1] = pNums[j];
j = j - 1;
}
pNums[j + 1] = key;
}
for ( i=k; i<N; i++)
{
cin>>x;
if(x>pNums[k-1])
{
for (int shifter=0; shifter<k; shifter++)
{
pNums[shifter]=x;
pNums[shifter] = pNums[shifter+1];
}
for (int r = 1; r <k; r++)
{
key = pNums[r];
j = r - 1;
while (j >= 0 && pNums[j] <key)
{
pNums[j + 1] = pNums[j];
j = j - 1;
}
pNums[j + 1] = key;
}
}
}
cout<<"pNums[k-1]:"<<pNums[k-1]<<endl;
}
This is my code, it compiles correctly but I got a different and incorrect result for pNums[k-1]. I think I am doing the shifting and removing the element at k-1 index operations incorrectly. N is the total number of elements, and I am using insertion sorting for the k-limited array.
This should help:
int AlgorithmSortK::select()
{
int N, x;
cin >> N; // number of the input elements
cout << "N:" << N << endl;
std::vector<int> nums;
nums.resize( k, std::numeric_limits<int>::min() ); // assume 'k' is defined elsewhere
for(int i=0; i<N; i++)
{
cin >> x; // get the next element
// shift it down while it's larger than existing numbers
for( int j=0; j<k; j++) {
if( x > nums[j] ) {
std::swap( x, nums[j] );
}
}
}
cout<<"nums[k-1]:" << nums[k-1]<<endl;
}
The complexity is O(N*k), could make it faster, but I'd rather have it simpler.
I am trying to find first smallest array but my code does not display any output. There are no errors or warnings. Actually, I am trying to check an algorithm that I got as an assignment from my university.
#include <iostream>
using namespace std;
int main(){
int arr[7]= {8,4,6,9,2,3,1};
int n = sizeof(arr)/sizeof(arr[0]);
int smallest = 0;
for(int j = 1; j = (n-1); j = (j + 1) )
{
smallest= j ;
for(int i = (j+1); i = n ; i = (i + 1))
{
if (arr[i]<arr[smallest])
{
smallest = i;
int swaper = arr[j];
arr[j] = arr[smallest];
arr[smallest] = swaper;
}
}
}
for(int a = 1; a = n; a = (a + 1))
{
cout<<arr[a];
}
return 0;
}
There are three errors with this code:
for(int a = 1; a = n; a = (a + 1))
{
cout<<arr[a];
}
Firstly, arrays start from zero, not one. So the first part of the for statement should be int a = 0;.
Secondly, you are not comparing a and n, you are assigning n to a, (and the value is non-zero, so you always keep going). The equality test is ==, but you don't want that anyway!
Thirdly, the loop condition is for when to keep going, not when to stop. So you need either < or != (either will work, people have long arguments about which is preferable).
The normal way to write a loop over a range of integers in C++ is:
for (int a = 0; a < n; a++)
You are at least consistent, and have made the same mistake in every loop. You will need to fix it in every loop.
# include <iostream>
using namespace std;
int main ()
{
int a[100][100],n,k,i,j,aux,mi=0;
cin>>n>>k;
for(i=1;i<=n;i++)
for(j=1;j<=k;j++)
cin>>a[i][j];
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++)
if(a[i][k]>a[j][k])
{aux=a[i][k];
a[i][k]=a[j][k];
a[j][k]=aux;
} //until here you are sorting the 2D array
for(i=1;i<=n;i++) {
for(j=1;j<=k;j++) {
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
mi=a[1][1];
for (i=1; i<=n; i++)
{
for (j=1; j<=n; j++)
if (mi<a[i][j])
mi=a[i][j];
} //here you're finding the smallest element
cout<<mi;
return 0;
}
The Code doesn't compile, but the idea should solve 90%, you just have to write the code.
I was doing my homework but don't know why bubble sort is not working. it is making first element of the array zero due to some unknown reason.
#include <iostream>
using namespace std;
int main()
{
int *arr,s;
cout<<"Enter the quantity of numbers ";
cin>>s;
arr=new int[s];
for(int i=0;i<s;i++)
{
cout<<"Enter number "<<i+1<<" ";
cin>>*(arr+i);
}
int temp;
for(int j=0;j<s;j++)
{
for(int k=0;k<(s-j);k++)
{
if(*(arr+k)>*(arr+k+1))
{
temp=*(arr+k);
*(arr+k)=*(arr+k+1);
*(arr+k+1)=temp;
}
}
}
for(int x=0;x<s;x++)
{
cout<<*(arr+x)<<"\t";
}
cout<<endl;
return 0;
}
OUTPUT
Enter the quantity of numbers 5
Enter number 1 4
Enter number 2 33
Enter number 3 22
Enter number 4 1
Enter number 5 3
0 1 3 4 22
I don't know why first element is getting zero. and if I run it without bubble sort loops it runs perfectly but don't with those loops.
In this for loop
for(int k=0;k<(s-j);k++)
{
if(*(arr+k)>*(arr+k+1))
^^^^^^^
{
temp=*(arr+k);
*(arr+k)=*(arr+k+1);
*(arr+k+1)=temp;
}
there is an attempt tp access memory beyond the array when j is equal to 0 and k is equal to s - 1. That is in this case k + 1 is equal to s though the valid range of indices is [0, s-1].
At least change the loops the following way
for(int j=0;j<s;j++)
{
for(int k = 1;k<(s-j);k++)
{
if(*(arr+k) < *(arr+k-1))
{
int temp=*(arr+k);
*(arr+k)=*(arr+k-1);
*(arr+k-1)=temp;
}
}
}
Your use of the index is off. You are picking up garbage values from outside your valid range (they just happen to be zeros). An easier style might help detect the problem.
for(int j=0;j<s;j++)
{
for(int k=1;k<s;k++)
{
if(arr[k-1]>arr[k])
{
int temp=arr[k];
arr[k]=arr[k-1];
arr[k-1]=temp;
}
Code
#include <bits/stdc++.h>
using namespace std;
int N, a[10050];
int main() {
scanf("%d", &N);
for (int i = 0; i < N; i++) scanf("%d" , &a[i]);
for (int k = 0; k < N; k++) {
int mn = k;
for (int i = k+1; i < N; ++i) {
if (a[i] < a[mn]) mn = i;
}
swap(a[k], a[mn]);
}
for (int i = 0; i < N; i++) printf("%d " , a[i]);
}
Explanation
In bubble sort, you swap the elements recursively. Here is a 15-line code. Hope it helps.