permutation in C++ - c++

class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > result;
vector<int> sofar;
permutehelper(nums, sofar, result);
return result;
}
void permutehelper(vector<int> &rest, vector<int> &sofar, vector<vector<int>> &ans){
if(rest.size() == 0) {
ans.push_back(sofar);
}
else{
for(int i = 0; i < rest.size(); i++){
sofar.push_back(rest[i]);
rest.erase(rest.begin() + i);
permutehelper(rest, sofar, ans);
}
}
}
};
How do I modify it to return all permutation, Currently it is giving only [[1,2,3]]. I know there are many solutions but I want to make it work using vectors sofar and rest.

You only have one rest vector (and only one sofar vector) because you are passing by reference. That means that when you remove an element from rest, it's gone. You never put it back, so it's gone forever. (In fact, you're removing elements from the vector passed as an argument to permute. Some would say that modifying the argument is poor interface design.)
You probably want to pass the parameter vectors by value (other than ans, which accumulates results and thus should be permanently modified). Of course, passing by value makes copies, which introduces an unnecessary quadratic complexity, but it will allow the algorithm to work as expected.

Related

Why is vector<vector<int>> slower than vector<int> []?

I was trying to solve leetcode323. My code and my way to solve the problem was basically identical to the official answer. The only difference was that I was using vector<vector> while the official answer used vector [] to keep the neighbors of each node. When I used vector [], the system accepted my answer. Is there any advantages of using vector [] over using vector<vector>? I put my code and the official solution code below. Thank you so much in advance.
My code:
class Solution {
public :
void explore(vector<bool> & visited,vector<int> nei[],int cur){
visited[cur]=true;
for(int i=0;i<nei[cur].size();i++){
if(!visited[nei[cur][i]]){
explore(visited,nei,nei[cur][i]);
}
}
}
public:
int countComponents(int n, vector<vector<int>>& edges) {
vector<bool> visited(n);
vector<vector<int>> neighbors(n);
int count=0;
for(int i=0;i<edges.size();i++){
neighbors[edges[i][0]].push_back(edges[i][1]);
neighbors[edges[i][1]].push_back(edges[i][0]);
}
for(int j=0;j<n;j++){
if(!visited[j]){
count++;
explore(visited,neighbors,j);
}
}
return count;
}
};
Official solution
class Solution {
public: void dfs(vector<int> adjList[], vector<int> &visited, int src) {
visited[src] = 1;
for (int i = 0; i < adjList[src].size(); i++) {
if (visited[adjList[src][i]] == 0) {
dfs(adjList, visited, adjList[src][i]);
}
}
}
int countComponents(int n, vector<vector<int>>& edges) {
if (n == 0) return 0;
int components = 0;
vector<int> visited(n, 0);
vector<int> adjList[n];
for (int i = 0; i < edges.size(); i++) {
adjList[edges[i][0]].push_back(edges[i][1]);
adjList[edges[i][1]].push_back(edges[i][0]);
}
for (int i = 0; i < n; i++) {
if (visited[i] == 0) {
components++;
dfs(adjList, visited, i);
}
}
return components;
}
};
I'm not sure, but I think the main problem of your solution is std::vector<bool> which is special case of std::vector.
In the '90s memory size was a problem. So to save memory std::vector<bool> is a specialization of std::vector template and single bits are used to store bool value.
This compacts memory, but comes with performance penalty. Now this has to remain forever to be compatible with already existing code.
I would recommend you to replace std::vector<bool> with std::vector<char> and do not change anything else. Let implicit conversion between bool and char do the magic.
Second candidate is missing reserve for adjList[i] as mentioned in other answer, but "official" solution doesn't do that either.
Here I refactor your code.
The only difference was that I was using vector<vector<int>>
There are several differences:
Official uses (non standard C++) VLA, whereas you use compliant vector<vector<int>>.
I would say that VLA "allocation" (similar to alloca) is faster than real allocation from std::vector (new[]).
From your test, assuming timing is done correctly, VLA seems to have a real impact.
Official use vector<int> whereas you use std::vector<bool>
With specialization, vector<bool> is more compact than std::vector<int /*or char*/> but would require a little more work to set/retrieve individual value.
You have some different names.
Naming difference should not impact runtime.
In some circonstance, very long difference and template usage might impact compilation time. But it should not be the case here.
Order of parameters of dfs/explore are different.
It might probably allow micro optimization in some cases, but swapping the 2 vectors doesn't seem to be relevant here.
Is there any advantages of using vector [] over using vector<vector>?
VLA is non standard C++, that is a big disadvantage.
Stack is generally more limited than heap, so size of "array" is more limited.
Its advantage seems to be a faster allocation.
The usage speed should be similar though.

No viable Overloaded. "=" C++

class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int k=0;
int m=nums1.size();
int n=nums2.size();
vector<int> res[m];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(nums1[i]==nums2[j]){
res[k]=nums1[i];
k++;
break;
}
}
}
return res;
}
};
I had to find duplicates in two different arrays and return the same. But I'm getting the error
no viable overloaded '='
from the compiler in the line where I am storing my duplicates in the res[k] vector.
In this line you try to allocate an array of std::vectors.
vector<int> res[m];
But m is not constant so it causes a compilation error (C++ does not support VLA - see Why aren't variable-length arrays part of the C++ standard?).
I am not sure what exactly you are trying to do, but I believe you should change it to:
vector<int> res;
Then use push_back to add elements to it:
res.push_back(nums1[i]); // Instead of: res[k]=nums1[i];
You don't need to track the number of elements in the vector with k and you can eliminate it altogether.
2 more notes:
The method intersect can be a static method (or a free functions) as it doesn't need access to any class members.
Your algorithm implementation compares each element in nums1 to each element in nums2 so you will get duplicates in the output array (not sure what was intended).

what's the difference between "vector<int>& a " and "vector<int> a"?

I'm the beginner in C++. I try to write a program to rotate a vector one by one
i.e., {1,2,3,4,5} --> {2,3,4,5,1} --> {3,4,5,1,2}
vector<vector<int>> allrot(const vector<int>& a)
{
vector<vector<int>> result;
for (int i = 0; i < a.size(); i ++ ){
rotate(a.begin(), a.begin() + 1, a.end());
result.push_back(a);
}
return result;
}
This doesn't work, and I have several questions.
Why should I use vector<int>& a rather than vector<int> a ?
What's wrong with my code ?
Thank you for your help
When you pass vector<int> then function gets a copy of that vector. You can do anything you want with it in the function and your original data would not change.
When you pass vector<int>& then function gets the reference which means that any changes in the function would modify the original data.

I am fairly new to STLs in C++ and i tried making a heap using vectors. Didnt get the desired output

#include<bits/stdc++.h>
using namespace std;
class Heap
{
vector <int> v;
int length;
public:
void create(vector <int> v, int s);
void display();
};
void Heap::create(vector <int> v, int s)
{
length=s+1;
for(int i=1;i<=s;i++)
{
this->v[i]=v[i-1];
}
int temp;
int j;
for(int i=2;i<length;i++)
{
temp=v[i];
j=i;
while(j>1&&temp>v[j/2])
{
swap(v[j],v[j/2]);
j=j/2;
}
if(j==1)
{
v[j]=temp;
}
}
}
void Heap::display()
{
for(int i=1;i<length;i++)
{
cout<<v[i]<<"\t";
}
cout<<endl;
}
int main()
{
vector <int> v;
int ans=1;
int d;
while(ans==1)
{
cout<<"Enter the Data\n";
cin>>d;
v.push_back(d);
cout<<"Do you want to enter more data?\n";
cin>>ans;
}
cout<<endl;
Heap h;
h.create(v,((int)v.size()));
h.display();
}
When i execute this code, it asks me to enter the data value. i enter all the data values i want to enter and click the enter button. it shows segmentation error. also the execution is taking a lot of time which is very unusaul. i use codeblocks version 20.
When i execute this code, it asks me to enter the data value. i enter all the data values i want to enter and click the enter button
Yeah, I'm not interested in guessing what you typed in order to reproduce your problem. I'm also not interested in guessing whether the issue is in your I/O code or the code you think you're testing.
Always remove interactive input when you're preparing a minimal reproducible example so that other people can actually reproduce it.
Sometimes removing the interactive input may fix your problem, in which case you've learnt something important (and probably want to ask a different question about your input code).
it shows segmentation error
A segmentation fault interrupts your program at the exact point where it happens. If you run your program in a debugger, it will show you where this is, and the state of everything in your program when it happened. You should try this, and learn to use your debugger.
this->v[i]=v[i-1];
As correctly pointed out in the other answer, there is a bug on this line.
You correctly called push_back when reading input, so you could just do the same here. Alternatively you need to explicitly size this->v before indexing elements that don't exist.
The other main problem with this function is that it mixes up this->v (used, illegally, only once on the line above) and v which is a local copy of the v in main, and which goes out of scope and is lost forever at the end of the function.
Just give your variables different names so you don't have to write this->v on all the other lines where you currently refer to v. Also, consider passing the original v by const ref instead of making a copy.
NB. I do see and understand that you're deliberately switching to 1-based indexing for the sort. If for some reason you can't just use std::sort or std::make_heap, you could at least explicitly set the zeroth element to zero, and then just std::copy the rest.
Finally, Heap::create really looks like it should just be a constructor. Forcing two-phase initialization is poor style in general, and I don't see any reason for it here.
First issue: you have used 'this->v' before initializing it. In this point:
this->v[i]=v[i-1];
this->v have size 0 and has no element to be accessed via index;
Furtheremore you have used wrong indices for it. Assuming this->v has initialized, correct index access is like this
this->v[i-1]=v[i-1];
Finally, it is better to sort the std vectors by using std::sort builtin function:
#include <algorithm>
std::sort(this->v.begin(), this->v.end());
This is obviously a school exercise. So I will only give you pointers as to where your code goes wrong.
class Heap
{
// vector <int> v; // v is not a suitable name for a class member, it's too short
// int length; // why length ? Your container declared above has length information, using
// a duplicate can only introduce opportunities for bugs!!!
vector<int> heap; // I've also renamed it in code below
public:
void create(vector <int> v, int s);
void display();
};
// some documentation is needed here...
// A I read it, it should be something like this, at least (this may reveal some bug):
//
// Initializes heap from range [v[1], v[s])
// void Heap::create(vector <int> v, int s) // you do not need a copy of the source vector!
void Heap::create(const vector& <int> v, int s) // use a const reference instead.
{
// This is not how you assign a vector from a range
// length=s+1;
// for(int i=1;i<=s;i++)
// {
// this->v[i]=v[i-1];
// }
// check inputs always, I'll throw, but you should decide how to handle errors
// This test assumes you want to start at v[1], see comment below.
if (0 > s || s >= v.size())
throw std::out_of_range ("parameter 's' is out of range in Heap::Create()");
// assign our private storage, why the offset by '1' ????
// I doubt this is a requirement of the assignment.
heap.assign(v.begin() + 1, v.begin() + s + 1);
//int temp; // these trivial variables are not needed outside the loop.
//int j;
// why '2' ?? what happens to the first element of heap?
// shouldn't the largest element be already stored there at this point?
// something is obviously missing before this line.
// you'll notice that v - the parameter - is used, and heap, our
// private storage is left unchanged by your code. Another hint
// that v is not suitable for a member name.
for(int i = 2; i < v.length(); i++)
{
int temp = v[i]; // temp defined here
int j = i;
//while(j > 1 && temp > v[j/2]) // avoid using while() when you can use for().
//{
// swap(v[j],v[j/2]);
// j=j/2;
//}
// This is your inner loop. it does not look quite right
for (; j > 1 && temp > v[j / 2]; j = j / 2)
swap(v[j], v[j/2]);
if (j == 1)
v[j] = temp;
}
}
void Heap::display()
{
for(int i=1;i<length;i++)
{
cout<<v[i]<<"\t";
}
cout<<endl;
}
From reading your code, it seems you forgot that vectors are zero-based arrays, i.e. The first element of vector v is v[0], and not v[1]. This creates all kinds of near unrecoverable errors in your code.
As a matter of personal preference, I'd declare Heap as deriving publicly from std::vector, instead of storing data in a member variable. Just something you should consider. You could use std::vector<>::at() to access and assign elements within the object.
As is, your code will not function correcly, even after fixing the memory access errors.

IOS C++ forbids comparison between pointer and integer (Not using strings)

I included the "not using strings" part in the title because when I was searching to find an answer on here I saw this problem a lot but it was with people using strings and getting chars mixed up. This is not my issue.
Trying to call an element of a 2D vector and see if it equals a certain number. I'm getting the comparison between pointer/integer error and I don't understand why. Here's my code, any help would be really appreciated.
bool UsedInRow(vector< vector<int> > vec(int n, vector<int> (int n)), int row, int num)
{
int n;
for (int col = 0; col < n; col++)
{
if (vec[row][col] == num)
{
return true;
}
}
return false;
}
Try this:
bool UsedInRow(const vector< vector<int> >& vec, int row, int num) { ... }
The expression you used vector< vector<int> > vec(int n, vector<int> (int n)) is actually a function pointer.
The compiler thinks that you are passing a function pointer.
Instead, pass the vector by reference:
bool UsedInRow(vector< vector<int> > &vec, int row, int num)
As the other answers point out, vec is a function pointer, not a vector.
You're being advised to change vec to a vector, but it's not clear that that's the right solution. There's no ambiguity in your declaration; vec is defined as a parameter of function pointer type.
If that's what you intended, you need to replace the reference to vec inside the function with a function call. For example, you might change
if (vec[row][col] == num)
to
if ((vec(42, something))[row][col] == num)
where something would itself have to be a function pointer, pointing to a function that takes an int argument and returns a vector<int> result.
The declaration of your UsedInRow function is quite complicated, and I can't tell how it's intended to be used.
If vec really should be just a vector, then you can make it one by deleting the (int n, vector<int> (int n)) part of the parameter declaration -- but then I'd have to wonder why you wrote it in the first place.
For a definitive answer, you'd need to explain to us what your UsedInRow function is supposed to do.