Well, recursion is always troublesome for me.
Can anyone explain me how recursion works in this function of calculating permutations of given string.
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
How does recursion works when there are 2 recursion calls followed by a statement in between? I hope i am clear.
Thanks.
Try to read the code out in english;
The function generates the perumtations the string a starting with the i'th element and ending with the n't element.
If i and n are equal we are done, there is only one element and only one permutation.
Otherwise;
For each j between i and n, inclusive in both ends.:
-Swap the position of the i'th element and the j'th element.
-Generate all permutations that does not change to order of the first i elements.
-Swap the i'th and j'th element back again.
The fact that the recursive call is in a loop means that it will be performed several times. - One time for each potenial first character of the string.
What the above means in a concrete example is that the algorithm will for the string "1234" do;
First generate the string that starts with "1" and is followed by all permuations of "234", ie all permutations of "1234" that happens to start with "1".
Then generate all permutations that starts with "2".
Then all that starts with "3".
And finaly all permuations that starts with "4".
Since all permutations of "1234" will start with "1","2","3" or "4", this will generate all permuations of the string "1234".
Proving that this works can be done by induction and "is left as an exercise for the reader".
Related
I am solving word break problem and I have used Dynamic Programming to optimise it, and the solution is working as well. But I am not able to calculate/figure out the time complexity of this approach.
Code:
class Solution {
public:
int util(string &s, int i, unordered_set<string> &dict, vector<int> &DP) {
if(i >= s.size()) {
return 1;
}
if(DP[i] != -1) {
return DP[i];
}
string next = "";
for(int itr = i; itr < s.size(); itr++) { // O(N)
next += s[itr];
if(dict.find(next) != dict.end() and util(s, itr+1, dict, DP)) { // ?
return DP[i] = 1;
}
}
return DP[i] = 0;
}
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.begin(), wordDict.end());
vector<int> DP(s.size() + 1, -1);
return util(s, 0, dict, DP);
}
};
Could anyone please help me to understand the time complexity of the above algorithm step-by-step?
Thanks
For each i ∈ [0..n) (n is length of s), your recursive function executes full inner loop exactly once (since the second time the result will be cached in DP).
At this point you might say that the whole algorithm is O(n²), but that is not true, there is a twist.
The inner loop which you labeled O(n) is not actually O(n), but O(n²), because you're searching next (substring of s) in the unordered_dict. Each such search takes O( next.length ) time, and, since length of next ranges from 0..length(s), the dict search is O(n), and the inner loop, consequently is O(n²).
Given all of the above, the whole algorithm is O(n³): O(n) from recursion and multiplied by O(n²) from inner loop.
Or, to be precise, O(n³ + k), where k is the cummulative size of all strings in the wordDict (since you're constructing set from them).
P.S. To reduce complexity by factor of O(n) you can use Trie instead of unordered_set to store words from wordDict. With that your algorithm would be O(n² + k).
I am trying to find its time complexity and found it to be O(n). Since each time loop is called we get time complexity of for loop getting decreased by one. So summing up number of times for loop runs each time print() is called, I got O(n). Am I right? Can you suggest me resources for learning more on time complexity of recursive functions?
pseudo code
print(n){
if(n==0)
return 0;
else
{
for(int i = 0 ; i < n ; i++)
{
printf("%d", i);
}
return print(n-1);
}
main(){
n=6;
print(n);
}
I'm not sure whether you are confused about time complexity of recursive functions or about how big O notation works.
To make sure we are on the same page consider the following example:
for (int i = n; i > 0; i++) {
for (int j = 0; j < i; j++) {
print(j)
}
}
The outer loop iterates n times and the inner loop iterates i-1 times for each iteration of the outer loop. The sequence of how many times the inner loop iterates is of the form: n, n-1,... 2, 1. This is equal to n * (n+1)/2.
What is happening in your code is quite similar to this nested loop.
At each stage of the function call, you check the base case n == 0, when it isn't true, code continues to print 0...n and recursively call itself with n-1. At some point, n == 0 and the base case hits and your function returns preemptively, before calling itself again.
This whole process is nothing else but the nested loops that I showed above. It's of the same time complexity. While the iterations aren't strictly n^2 in big O notation we only care about the highest degree member of each quantity. That's why time complexity is quadratic.
The problem is derive from OJ.
The description is :
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.
However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.
I write small snippet about MinMax problem in recursion. But it is slow and I want to rewrite it in a iterative way. Could anyone help with that and give me the idea about how you convert the recursive solution to iterative one? Any idea is appreciated. The code is showed below:
public int getMoneyAmount(int n) {
int[][] dp = new int[n + 1][n + 1];
for(int i = 0; i < dp.length; i++)
Arrays.fill(dp[i], -1);
return solve(dp, 1, n);
}
private int solve(int[][] dp, int left, int right){
if(left >= right){
return 0;
}
if(dp[left][right] != -1){
return dp[left][right];
}
dp[left][right] = Integer.MAX_VALUE;
for(int i = left; i <= right; i++){
dp[left][right] = Math.min(dp[left][right], i + Math.max(solve(dp, left, i - 1),solve(dp, i + 1, right)));
}
return dp[left][right];
}
In general, you convert using some focused concepts:
Replace the recursion with a while loop -- or a for loop, if you can pre-determine how many iterations you need (which you can do in this case).
Within the loop, check for the recursion's termination conditions; when you hit one of those, skip the rest of the loop.
Maintain local variables to replace the parameters and return value.
The loop termination is completion of the entire problem. In your case, this would be filling out the entire dp array.
The loop body consists of the computations that are currently in your recursion step: preparing the arguments for the recursive call.
Your general approach is to step through a nested (2-D) loop to fill out your array, starting from the simplest cases (left = right) and working your way to the far corner (left = 1, right = n). Note that your main diagonal is 0 (initialize that before you get into the loop), and your lower triangle is unused (don't even bother to initialize it).
For the loop body, you should be able to derive how to fill in each succeeding diagonal (one element shorter in each iteration) from the one you just did. That assignment statement is the body. In this case, you don't need the recursion termination conditions: the one that returns 0 is what you cover in initialization; the other you never hit, controlling left and right with your loop indices.
Are these enough hints to get you moving?
I have some elements in a QMap<double, double> a-element. Now I want to get a vector of some values of a. The easiest approach would be (for me):
int length = x1-x0;
QVector<double> retVec;
for(int i = x0; i < length; i++)
{
retVec.push_back(a.values(i));
}
with x1 and x0 as the stop- and start-positions of the elements to be copied. But is there a faster way instead of using this for-loop?
Edit: With "faster" I mean both faster to type and (not possible, as pointed out) a faster execution. As it has been pointed out, values(i) is not working as expected, thus I will leave it here as pseudo-code until I found a better_working replacement.
Maybe this works:
QVector<double>::fromList(a.values().mid(x0, length));
The idea is to get all the values as a list of doubles, extract the sublist you are interested in, thus create a vector from that list by means of an already existent static method of QVector .
EDIT
As suggested in the comments and in the updated question, it follows a slower to type but faster solution:
QVector<double> v{length};
auto it = a.cbegin()+x0;
for(auto last = it+length; it != last; it++) {
v.push_back(it.value());
}
I assume that x0 and length take care of the actual length of the key list, so a.cbegin()+x0 is valid and it doesn't worth to add the guard it != a.cend() as well.
Try this, shouldn work, haven't tested it:
int length = x1-x0;
QVector<double> retVec;
retVec.reserve(length); // reserve to avoid reallocations
QMap<double, double>::const_iterator i = map.constBegin();
i += x0; // increment to range start
while (length--) retVec << i++.value(); // add value to vector and advance iterator
This assumes the map has actually enough elements, thus the iterator is not tested before use.
I was given a problem to create a recursive function that prints out even numbers from 0 to the passed number. My problem? It can only have one parameter: int counting(int n). I can't figure out how to do this. There are no loops in the main. You have to start at 0, but somehow get it to the value you're passing.
Any ideas on the method?
With recursion, you want to think of the base case (the case at which the recursion will stop and you'll start returning up the call stack). In this case, your method needs to keep calling itself until it gets down to 0. This implies that you'd need to keep calling it after reducing the parameter by 1 until the value reaches 0. Then you'd need to check whether the number is even or not and, if so, print the number.
Here's an example:
def printeven(n):
if n > 0:
printeven(n-1)
if n % 2 ==0:
print n
Make the recursive call before the printing - it will do the trick.
In Java:
int counting(int n) {
if (n == 0)
return n;
int res = counting(n - 1);
if (n % 2 == 0)
System.out.println(n);
return res;
}
The codes everyone gave is the same including this one in c.
int counting(int n) {
if(n)
counting(n-1);
if(!(n%2))
printf("%d\n", n);
}
The trick is to keep recursing until the parameter reaches 0, then start printing the number before returning to the caller.