CareerCup chapter 8 Recursion

8.1 Write a method to generate the nth Fibonacci number.

     Recursive solution:

     int fib(n){

           if(n==0)return 0;

           else if(n==1)return 1;

           else if(n>1)return fib(n-1)+fib(n-2);

           else return -1;

     }

     Iterative solution:

     int fib(n){

         if(n==0)return 0;

         else if(n==1)return 1;

         else if(n>1){

                 int a=0,b=1;

                 for(int i=1;i<n;i++){

                      int c=a+b;

                      a=b;

                      b=c;

                 }

                 return b;

          }else return -1;

     }

8.2 Imagine a robot sitting on the upper left hand corner of an NxN grid. The robot can only move in two directions: right and down How many possible paths are there for the robot?
FOLLOW UP
Imagine certain squares are “off limits”, such that the robot can not step on them Design an algorithm to get all possible paths for the robot.

      Part 1: the path to (x,y) point is path to(x,y-1)+path(x-1,y).

      int gridSum(int n){

           if(n<=0)return -1;

           vector<int> f[2];

           for(int i=0;i<n;i++){

                 f[0].push_back(1);

                 f[1].push_back(1);

            }

            int cur=0,pre=1;

            for(int i=1;i<n;i++){

                 cur=!cur;pre=!pre;

                 f[cur][0]=1;

                 for(int i=1;i<n;i++){

                      f[cur][i]=f[cur][i-1]+f[pre][i];

                 }

            }

            return f[cur][n-1];

      }

     Part1: we known that, if we want to visit (x,y), we should move right x-1 times and move down y-1 times, the different path is how we arrange right moving and down moving, so the sum path is C(x-1+y-1,x-1),即(x-1+y-1)!/((x-1)!*(y-1)!)。

     Part2: when we meet "off limits" square, we assign the sum path to this to 0.

8.3 Write a method that returns all subsets of a set.

     Method1: we can think this a DP problem, for example, a set is {1 3 4}, we can think the set is {1 3} + {4}, when it comes to {1 3},the subsets is{}{1}{3}{1 3},when we add {4} to this set, the subsets will add {4} to all pre subsets, we also store all pre subsets, and the subsets of {1 3 4} are {}{1}{3}{1 3}{4}{1 4}{3 4}{1 3 4}.

     vector<vector<int> > allSubsets(vector<int> num){

           vector<vector<int> > res(1);

           if(num.size()==0)return res;

           for(int i=0;i<num.size();i++){

                 int curLen = res.size();

                 for(int j=0;j<curLen;j++){

                        vector<int> temp=res[j];

                        temp.push_back(num[i]);

                        res.push_back(temp);

                 }

           }

           return res;

     }

     Method2: each subset is to ask whether a element chosen or not, and the sum subsets is 2^n. so, we can simulate this process by traversing 0~2^n num and see a element chosen or not based on its binary number(0 or 1).

     vector<vector<int> > allSubsets(vector<int> num){

            vector<vector<int> > res;

            vector<int> temp;

            int maxNum = 1<<res.size();

            for(int i=0;i<maxNum;i++){

                  int k=i,index=0;

                  temp.clear();

                  while(k>0){

                         if(k&1>0)temp.push_back(num[index]);

                         k=k>>1;

                         index++;

                   }

                   res.push_back(temp);

            }

            return res;

     }

8.4 Write a method to compute all permutations of a string.

      the first char, we can chose from all chars of this string, and second char, we chose from all chars of this string except the first char, then the third....., so we can DFS this string to compute all permutations.

      void DFS(vector<string> &res,string &temp,string &s,int cur){

               if(cur==s.length()){res.push_back(temp);return;}

               else{

                     for(int i=cur;i<s.length();i++){

                           if(i!=cur)swap(s[i],s[cur]);

                           temp.push_back(s[cur]);

                           DFS(res,temp,s,cur+1);

                           temp.pop_back();

                     }

               }

      } 

      vector<string> permutations(string &s){

              vector<string> res;

              string temp;

              DFS(res,temp,s,0);

              return res;

      }

8.5 Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-pairs of parentheses.
EXAMPLE:
input: 3 (e.g., 3 pairs of parentheses) output: ()()(), ()(()), (())(), ((()))

     we also use DFS by declare a stack to store left parentheses at current time. We judge leftP<rightP to add right parentheses.

class Solution {
public:
    void combinDFS(vector<string> &res,string &temp,int leftP,int rightP){
            if(rightP==0){res.push_back(temp);return;}
            else{
                   if(leftP>=rightP){
                         temp.push_back('(');
                         combinDFS(res,temp,leftP-1,rightP);
                         temp.pop_back();
                   }else{
                        if(leftP>0){
                              temp.push_back('(');
                              combinDFS(res,temp,leftP-1,rightP);
                              temp.pop_back();
                        }
                        temp.push_back(')');
                        combinDFS(res,temp,leftP,rightP-1);
                        temp.pop_back();
                   }
            }
     }
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        if(n==0)return res;
        string temp;
        combinDFS(res,temp,n,n);
        return res;
    }
};

8.6 Implement the “paint fill” function that one might see on many image editing programs. That is, given a screen (represented by a 2-dimensional array of Colors), a point, and a new color, fill in the surrounding area until you hit a border of that color.

     begin at this point, move to four adjacent points, if a point color is equal to the beginning, we change the point color to new color.  

enum Color{Black,Green,White,Yellow,Red,Gray};
void paintFillRec(vector<vector<Color> > &screen,int x,int y,Color oldColor,Color newColor){
    if(x<0||x>=screen[0].size())return;
    if(y<0||y>=screen.size())return;
    if(screen[y][x]==oldColor){
        screen[y][x]=newColor;
        paintFillRec(screen, x-1, y, oldColor, newColor);
        paintFillRec(screen, x+1, y, oldColor, newColor);
        paintFillRec(screen, x, y-1, oldColor, newColor);
        paintFillRec(screen, x, y+1, oldColor, newColor);
    }
    return;
}
void paintFill(vector<vector<Color> > &screen,int x,int y,Color newColor){
    paintFillRec(screen,x,y,screen[y][x],newColor);
}

8.7 Given an infinite number of quarters (25 cents), dimes (10 cents), nickels (5 cents) and pennies (1 cent), write code to calculate the number of ways of representing n cents.

    Method1:first, we only use pennies to represent n cents, then, we change every 5 pennies to a nickel, this is the second layer, if there is more than 2 nickels, we can change every 2 nickels to a dimes, this is the third layer. And in the fourth layer, we rule that every 2 dimes and 1nickel can change to a quarter.

    int numWays(int n){

          int num=1;

          int a[3]={n,0,0};

          while(a[0]>=5){

               a[0]-=5;a[1]++;num++;

               int a1=a[1];

               while(a1>=2){

                     a1-=2;a[2]++;num++;

                     int a2=a[2];

                     while(a1>0&&a2>=2){

                              a1--;a2-=2;num++;

                     }

               }

               a[2]=0;

          }

          return num;

    }

    **Method2: we begin from the biggest value, here is quarters(25 cents), we deduce 25 from n, and then find sum represents of n-25.

<span style="font-size:14px;">int numWays(int n,int denom){
    int nextDenom=0;
    switch (denom) {
        case 25:
            nextDenom=10;
            break;
        case 10:
            nextDenom=5;
            break;
        case 5:
            nextDenom = 1;
            break;
        case 1:
            return 1;
    }
    int ways=0;
    for(int i=0;i*denom<=n;i++){
        ways+=numWays(n-i*denom, nextDenom);
    }
    return ways;
}</span>

8.8 Write an algorithm to print all ways of arranging eight queens on a chess board so that none of them share the same row, column or diagonal.

你可能感兴趣的:(LeetCode)