leetcode Question 60: N-Queens II

N-Queens II

Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.

Analysis:

Same idea just a little bit difference from the previous one.

Note:
If I use the vector as the data structure, the code cannot pass the large online judge, however, if I use the dynamic array, which successfully pass all the online judge test. What the hell? lol


Source Code:

class Solution {
public:
    int res;
     
    bool isValid(int A[], int r){
        for (int i=0;i<r;i++){
            if ( (A[i]==A[r])||(abs(A[i]-A[r])==(r-i))){
                return false;
            }
        }
        return true;
    }
    void nqueens(int A[], int cur, int n){
        if (cur==n){ res++;return;}
        else{
            for (int i=0;i<n;i++){
                A[cur]=i;
                if (isValid(A,cur)){
                    nqueens(A,cur+1,n);
                }
            }
        }
    }
    int totalNQueens(int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        res=0;
        int *A = new int[n];
        nqueens(A,0,n);
        return res;
    }
};

leetcode Question 59: N-Queens

N-Queens

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]

Analysis:

The classic recursive problem.
1. Use a int vector to store the current state,  A[i]=j refers that the ith row and jth column is placed a queen.
2. Valid state:  not in the same column, which is A[i]!=A[current], not in the same diagonal direction: abs(A[i]-A[current]) != r-i

3. Recursion:
       Start:   placeQueen(0,n)
        if current ==n then print result
        else
            for each place less than n,
                 place queen
                if current state is valid, then place next queen   place Queen(cur+1,n)
           end for
        end if


Source Code:

class Solution {
public:

    vector<vector<string> > res;
    
    void printres(vector<int> A,int n){
        vector<string> r;
        for(int i=0;i<n;i++){
            string str(n,'.');
            str[A[i]]='Q';
            r.push_back(str);
        }
        res.push_back(r);
    }
    
    
    bool isValid(vector<int> A, int r){
        for (int i=0;i<r;i++){
            if ( (A[i]==A[r])||(abs(A[i]-A[r])==(r-i))){
                return false;
            }
        }
        return true;
    }
    
    void nqueens(vector<int> A, int cur, int n){
        if (cur==n){printres(A,n);}
        else{
            for (int i=0;i<n;i++){
                A[cur]=i;
                if (isValid(A,cur)){
                    nqueens(A,cur+1,n);
                }
            }
        }
    }
     
    vector<vector<string> > solveNQueens(int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        res.clear();
        vector<int> A(n,-1);
        nqueens(A,0,n);
        return res;
    }
};

leetcode Question 58: Multiply Strings

Multiply Strings


Given two numbers represented as strings, return multiplication of the numbers as a string.
Note: The numbers can be arbitrarily large and are non-negative.


Analysis:

Straight forward idea. Just like the way we multiply numbers. Don't forget considering the carry and be careful. e.g.

  123*456,

what we usually do is:


      123
*    456
-----------

      738
    615
+492
-----------
  56088
thus, 123*456 = 56088.

In the same way, the algorithm is:
A*B
(1)For each element B[i]
    Compute tmp = B[i]*A
    Add tmp to the previous result, note the start position. res = res"+"tmp
(2)Return result.

To be specific,
(1) char2int,     int(char-'0');
(2) int2char,     char(int+'0')
(3) Don't forget the carry in each add or multiply operation.
(4) Don't forget the carry after last operation. e.g.  82+33 = 115.
(5) Be careful with the string order and the number order.


Update (201309) Code:


class Solution {
public:

    string mpl(string num, char n){  //compute num*n
        string res="";
        int carry=0;    
        if (n=='0'){return "0";}
        for (int i=num.size()-1;i>=0;i--){
            int m=(num[i]-'0')*(n-'0')+carry;
            carry = m/10;
            m=m%10;
            res = char(m+'0')+res;
        }
        if (carry!=0){res = char(carry+'0')+res;}
        return res;
    }

    void add(string &res, string m,int idx){
        if (res==""){ res = m;}
        else{
            m = m+string(idx,'0'); // this is important (you can also change value i instead)
            int carry=0;
            int i=res.size()-1;
            int j=m.size()-1;
            while (i>=0){
                int k =(res[i]-'0')+(m[j]-'0')+carry;
                carry=k/10;
                k=k%10;
                res[i]=char(k+'0');
                i--; j--;
            }
            while (j>=0){ // deal with the rest of string
                if (carry>0){
                    int kk = (m[j]-'0')+carry;
                    carry = kk/10;
                    kk=kk%10;
                    res= char(kk+'0')+res;
                }else{
                    res = m[j]+res;
                }
                j--;
            }
            
            if (carry>0){ // be careful with highest digit
                res = char(carry+'0')+res;
            }
        }
    }

    string multiply(string num1, string num2) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function                
        if (num1.size()==0 || num2.size()==0){return "";}
        //handle negative case
        bool pos=true; 
        if (num1[0]=='-'){num1=num1.substr(1);pos = !pos;}
        if (num2[0]=='-'){num2=num2.substr(1);pos = !pos;}

        //main part
        string res="0";        
        for (int i=num2.size()-1;i>=0;i--){ //for each element in num2        
            string m=mpl(num1,num2[i]); // num1 multiply by num2[i]           
            if (m!="0"){
                add(res,m,num2.size()-1-i); // add m to the result
            }
        }
                
        if (!pos){res="-"+res;}
        return res;
    }
};
 

leetcode Question 57: Minimum Window Substring

Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC".
Note:
If there is no such window in S that covers all characters in T, return the emtpy string "".
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

Analysis:

Generally speaking, the idea of this problem is not straightforward, implementation is not easy, it is a difficult problem!!!

The idea is like this:
   We have two pointers, p and q.  S[p:q] stores the string covers all the chars in T. We want minimum p:q.
   Start from the whole S, p=0, q=S.size()-1,  if it cannot cover T, return "";
   Fix p, try to move q close to p, but keep the requirement S[p:q] covers T.
   Find the shortest p:q, here exactly is 1:q, where S[1:q] covers T.
   Move p and q dynamically:
        if  S[p] is irrelevant char, p++;
        if  S[p] is char in T, must move q to left until find S[q]==S[p] to keep the requirement, or q is last.
            When move q to left, if S[q] is in T, store the S[q] occurrence.
   Every move, compare the length p:q store the minimum length and position.

 
   To check if the S[p:q] covers T, because the complexity requirement, the idea goes as follows:
   (1)  use map<char, int>,  to store the occurrence of chars in S and T. Be careful with the duplicate case.
   (2)  Check the occurrence of mapS and mapT, if mapS[T[i]]<mapT[T[i]], return false;
    After find the first covered string [1:q], we do like one-by-one move, so the cover test can only be the occurrence of the first char S[p], and when move q, don't forget add occurrence if meets S[q] in T.

 
See code below for more  details. Both small and large tests are passed



Code(201309):

class Solution {
public:
    string minWindow(string S, string T) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (S.size()<T.size()){return "";}
            
        map<char,int>mp; // store chars occurrence of T 
        for(int i=0;i<T.size();i++){mp[T[i]]++;}
        
        int res_len=INT_MAX; // result length
        int res_p=0;//result start posiion
        
        int p=0; //pointer start
        int q=S.size()-1; //pointer end
        
        while (mp[S[p]]==0){if(p>=S.size()){return "";} p++;} //remove irralevent starting chars
        while (mp[S[p]]==0){q--;if(q<0){return "";}} // remove irralevent ending chars
        
        map<char,int> tab; //store chars occurrence of S[p:q]
        for (int i=p;i<=q;i++){tab[S[i]]++;} 
                    
        while (tab[S[q]]>mp[S[q]] || mp[S[q]]==0){ // move q to left find the 1st covered substring
           tab[S[q]]--;
           q--;
        }
            
        for (int i=0;i<T.size();i++){  // if no covered substring found, return ""
            if (tab[T[i]]<mp[T[i]]){return "";}
        }
    
        if (q-p+1<res_len){res_len=q-p+1; res_p=p;} //store the result
        
        
        while (p<q){
            if (q-p+1<res_len){res_len=q-p+1; res_p=p;} //store the result
            if (mp[S[p]]==0){p++;continue;} // if current char is not in T, go next
            if (tab[S[p]]>mp[S[p]]){tab[S[p]]--;p++;continue;} // if more chars in this substring, go next
            
            q++; 
            while (q<S.size() && S[q]!=S[p]){ if (mp[S[q]]>0){tab[S[q]]++;} q++;} //move q to find a substring covers T
            if (q>=S.size()){q=S.size()-1;}else{tab[S[q]]++;}
            
            if (S[q]==S[p]){ tab[S[p]]--; if (tab[S[p]]<mp[S[p]]){break;} p++;continue;}        
            break;
        }
        
        return S.substr(res_p,res_len);
    }
};

leetcode Question 56: Minimum Path Sum

Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.


Analysis:
This is a DP problem.
Init: A[0][i] = A[0][i-1]+grid[0][i];
      A[i][0] = A[i-1][0]+grid[i][0];
State Change func:
      A[i][j] = min(A[i-1][j]+grid[i][j], A[i][j-1]+grid[i][j]);


Source Code:
class Solution {
public:
    int minPathSum(vector<vector<int> > &grid) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (grid.empty()){return 0;}
        int m=grid.size();
        int n=(*grid.begin()).size();
        vector<vector<int> > a(m,vector<int>(n,0));      
        a[0][0]=grid[0][0];
        for (int i=1;i<n;i++){ a[0][i]=a[0][i-1]+grid[0][i];}
        for (int i=1;i<m;i++){ a[i][0]=a[i-1][0]+grid[i][0];}    
        for(int i=1;i<m;i++){
            for (int j=1;j<n;j++){
                a[i][j]= min( a[i][j-1]+grid[i][j], a[i-1][j]+grid[i][j]);
            }
        }
        return a[m-1][n-1];
    }
};

leetcode Question 55: Minimum Depth of Binary Tree

Minimum Depth of Binary Tree

Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

Analysis:


Both DFS and BFS can work for this problem. Since the aim is to find the shortest path, BFS might be a better idea. A queue is used to save every node from the binary tree in depth order. Pop each node, and push its left child and right child (if exist). If the current node is the leaf node (no left and right children), return its depth.  To store the depth of each node, we can use a pair structure <TreeNode* int>.

Note: 
pair<TreeNode*, int> is a good data structure to save the node as well as its depth.

pair constructor  :   (1) pair<TreeNode* int>(node, dep);
                              (2) make_pair(node,dep);

Code(C++):


/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int minDepth(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        queue< pair<TreeNode*,int> > q;
        int i=0;
        if (!root){return 0;}
        q.push(make_pair(root,1));
        while(!q.empty()){
            pair<TreeNode*,int> cur = q.front();
            q.pop();
            if (!cur.first->left && !cur.first->right){
                return cur.second;
            }
            if(cur.first->left){
                q.push(make_pair(cur.first->left,cur.second+1));
            }
            if(cur.first->right){
                q.push(make_pair(cur.first->right,cur.second+1));
            }
        }
    }
};

Code(Python):

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param root, a tree node
    # @return an integer
    def maxDepth(self, root):
        if root == None:
            return 0
        q = []
        q.append([root, 1])
        res = 0
        while len(q) != 0:
            node, dep = q.pop()
            res = max(res, dep)
            if node.left != None:
                q.append([node.left, dep + 1])
            if node.right != None:
                q.append([node.right, dep + 1])
        return res
            
        
        
        

leetcode Question 54: Merge Two Sorted Lists

Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.


Analysis:



The idea is relative simple, add one list into the other. 
Consider the following conditions:
1. The l1 is empty. Then l2 is the result.
2. current element in l1 > current element in l2, insert current element in l2 before current element of l1.
3. current element in l1 < current element in l2, goto the next element in l1 and compare again.
Step 2 and 3 are in the loop, until l2 is empty.


Code (updated 201403):

This version of code is easy to understand, where one node is used to hold the head of the result (for output), another node is used for the tail of the result list (for insertion), every time check (1) the empty case, (2) the value comparison, and insert proper node into the result list, this will solve the problem. See code below:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        ListNode* res = new ListNode(0);
        ListNode* current = res;
        while (true){
            if (!l1){
                current->next = l2;
                break;
            }
            if (!l2){
                current->next = l1;
                break;
            }
            if (l1->val < l2->val){
                current->next = l1;
                l1 = l1->next;
            }else{
                current->next = l2;
                l2 = l2->next;
            }
            current = current->next;
        }
        return res->next;
    }
};




Code(updated 201401):

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        if (!l1){return l2;} //if l1 empty, return l2
        if (!l2){return l1;} //if l2 empty, return l1
        ListNode *q=new ListNode(0); //megere l2 into l1
        q->next = l1;
        l1 = q;
        ListNode *p = l2;
        while (p){ //loop to l2 end 
            if (q->next){ // if l1 is not end
                if (p->val<q->next->val){ //if l2 value < l1 vaule, then insert
                    ListNode* tmp;
                    tmp=q->next;
                    q->next = p;
                    p=p->next;
                    q->next->next = tmp;
                }else{q=q->next;} // else goto the next l1 element.
            }else{ // if l1 is end, just link the remaining of l2 to the end and return
                q->next=p;
                return l1->next;
            }
        }
        return l1->next;
    }
};



Code(old version):




/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* merg2(ListNode* l1, ListNode* l2){
        ListNode* head = new ListNode(0);
        head->next = l1;
        ListNode* prev = head;
        if (l1==NULL){
            head->next=l2;
        }
        while (l1!=NULL && l2!=NULL){
            if (l1->val < l2->val){
                if (l1->next != NULL){
                    prev = l1;
                    l1=l1->next;
                }else{
                    l1->next = l2;
                    break;
                }
            }else{
                ListNode* tmp = l2->next;
                prev->next = l2;
                l2->next = l1;
                prev = l2;
                l2 = tmp;
            }
        }
        return head->next;
    }
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        return merg2(l1,l2);
    }
};

leetcode Question 53: Merge Sorted Array

Merge Sorted Array

Given two sorted integer arrays A and B, merge B into A as one sorted array.
Note:
You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.

Analysis:
The classic problem. (can be found in the book "Cracking the Code Interview").
Part of the merge sort, merge the arrays from the back by comparing the elements.

Code(Updated 201309):

class Solution {
public:
    void merge(int A[], int m, int B[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int count=m+n-1;
        m--; n--;
        while (m>=0 && n>=0){
            A[count--] = A[m]>B[n]? A[m--]:B[n--];
        }
        while (n>=0){ A[count--] = B[n--];}
    }
};

Code(Old version):

class Solution {
public:
    void merge(int A[], int m, int B[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int k=m+n-1;
        int i=m-1;
        int j=n-1; 
        while (i>=0 && j>=0){
            if (A[i]>B[j]){
                A[k--]=A[i--];
            }else{
                A[k--]=B[j--];
            }
        }
        while (j>=0){
            A[k--]=B[j--];
        }
        return;
    }
};

leetcode Question 52: Merge k Sorted Lists


Merge Sorted Array
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Analysis:
While the lists is not empty, keep merging the list to the result list. Method to merge two lists is the same as Question 54

Code(updated 201309):
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        ListNode* head=new ListNode(0);
        if (lists.size()==0){return NULL;}
        head->next = lists[0];
        ListNode *p;
        ListNode *q;
        for (int i=1;i<lists.size();i++){
            p = head;
            q = lists[i];
            while (q){
                if (!p->next){
                    p->next = q;
                    break;
                }
                if (p->next->val<q->val){
                    p=p->next;
                }else{
                    ListNode *l = p->next;
                    p->next = q;
                    q=q->next;
                    p->next->next = l;
                    p=p->next;
                }
            }
        }
        return head->next;
    }
};






Code(old version):


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* merg2(ListNode* l1, ListNode* l2){
        ListNode* head = new ListNode(0);
        head->next = l1;
        ListNode* prev = head;
        if (l1==NULL){
            head->next=l2;
        }
        while (l1!=NULL && l2!=NULL){
            if (l1->val < l2->val){
                if (l1->next != NULL){
                    prev = l1;
                    l1=l1->next;
                }else{
                    l1->next = l2;
                    break;
                }
            }else{
                ListNode* tmp = l2->next;
                prev->next = l2;
                l2->next = l1;
                prev = l2;
                l2 = tmp;
            }
        }
        return head->next;
    }
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (lists.empty()){return NULL;}
        ListNode *head = lists.back();
        lists.pop_back();
        while (!lists.empty()){
            head = merg2(head,lists.back());
            lists.pop_back();
        }
        return head;
    }

leetcode Question 51: Merge Intervals

Merge Intervals


Given a collection of intervals, merge all overlapping intervals.
For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].


Analysis:

To check the intersections between interval [a,b] and [c,d],  there are four cases (equal not shown in the figures):
    a____b
c____d

a____b
     c____d

a_______b
    c___d

   a___b
c_______d

But we can simplify these into 2 cases when check the smaller (smaller start point) interval with the bigger interval.

For the problem, the idea is simple. First sort the vector according to the start value. Second, scan every interval, if it can be merged to the previous one, then merge them, else push it into the result vector.

Note here:
The use of std::sort to sort the vector, need to define a compare function, which need to be static. (static bool myfunc() ) The sort command should be like this:  std::sort(intervals.begin,intervals.end, Solution::myfunc); otherwise, it won't work properly.

If using python, the sort function is much easier with the lambda func.

Code (C++):


/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    static bool myfunc(const Interval &a, const Interval &b){
        return (a.start < b.start);
    }
    vector<Interval> merge(vector<Interval> &intervals) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<Interval> res;
        if (intervals.size()==0){return res;}
        std::sort(intervals.begin(),intervals.end(),Solution::myfunc);
        res.push_back(intervals[0]);
        for (int i=1;i<intervals.size();i++){
            if (res.back().end>=intervals[i].start){
                res.back().end=max(res.back().end,intervals[i].end);
            }else{
                res.push_back(intervals[i]);
            }   
        }
        return res;
    }
};



Code(Python):

# Definition for an interval.
# class Interval:
#     def __init__(self, s=0, e=0):
#         self.start = s
#         self.end = e

class Solution:
    # @param intervals, a list of Interval
    # @return a list of Interval
    def merge(self, intervals):
        res = []    # result list
        
        if len(intervals)==0:
            return res
        
        #sort list according to the start value    
        intervals.sort(key=lambda x:x.start)
        
        res.append(intervals[0])
        
        #scan the list
        for i in xrange(1,len(intervals)):
            cur = intervals[i]
            pre = res[-1]
            #check if current interval intersects with previous one
            if cur.start <= pre.end:
                res[-1].end = max(pre.end, cur.end) #merge
            else:
                res.append(cur) #insert
                
        return res
            
            

leetcode Question 50: Median of Two Sorted Arrays

Median of Two Sorted Arrays

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Analysis:

Note that the definition of the Median:
(1) If the size of the sequence N is odd: N/2+1th element is median.
(1) If the size of the sequence N is even:  average of the N/2th and N/2+1th element is median.

So in this problem, median of the two sorted arrays is the (m+n)/2+1 th element (if m+n is odd), the average of (m+n)/2 th and (m+n)/2+1 th  (if m+n is even).
E.g.,  [1,2,3],[5,6,7], the median is (3+5)/2 = 4.0.
          [1,2,3,4], [1,3,5,7,9], the median is 3.

Our task becomes finding the Kth (K or K+1, K=(m+n)/2) number in two sorted arrays, in O(log(m+n)) time constraint (what's in your mind to see log? Yes, binary search).

Similar to but slight different from binary search, we still divide K into two halves each time. Two pointers are used for each array, so that we can compare which side is smaller (?A[pa]>B[pb]).
E.g., A = [1,3,5,7,9]  B = [2,4,8,10,12,14,16,18]. K=(5+8) /2= 6.

pa = K/2 = 3;
pb = K-pa = 3;
         pa
A[1,3,5,7,9]
         pb
B[2,4,8,10,12,14,16,18]

if (A[pa]<B[pb]), which means the elements from A[0] to A[pa] must exist in the first Kth elements.
The next step now becomes finding the (K-pa) th (equals to K/2) element in the array A[pa:end] and B[].  This procedure can be viewed as "cutting" K/2 elements from the "smaller" array, and continue find the other K/2 th elements from the "bigger" array and the array after the cut. Note that smaller and bigger here is the comparison of the last elements.

if (A[pa]>B[pb]), the same procedure is applied but we "cut" the B array.

In this way, every time we have "cut" K/2 elements from one of the arrays, the next time is to cut (K/2) /2 elements from the new arrays, until:
(1) K=1, the smaller one from A[0] and B[0] is the "Kth element".
(2) One of the array meets the end. Then just return the current Kth element from the other array.



Misc. In C++, the array pointer is relative easy, (1) the array alone name represents the pointer pointed to the first element of the array, and pointer+n points to the nth element of the array. e.g.
double [3] arr = {1.0,2.0,3.0};
double *p = arr;        // *p=arr[0]=1.0;
p=p+2;                     //*p=arr[2]=3.0;



Code(C++):


class Solution {
public:

    double fms(int A[], int m, int B[], int n, int k){
        
        if (m>n) {return fms(B,n,A,m,k);}
        
        if (m==0) { return B[k-1];}
        if (k==1) { return min(A[0],B[0]);}
        int pa = min(k/2,m);
        int pb = k-pa;
        if (A[pa-1]<=B[pb-1]) {return fms(A+pa,m-pa,B,n,k-pa);}
        return fms(A,m,B+pb,n-pb,k-pb);
    }

    double findMedianSortedArrays(int A[], int m, int B[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int total = m + n;
        if(total%2==1){
            return fms(A,m,B,n,total/2+1);
        }else{
            return (fms(A,m,B,n,total/2)+fms(A,m,B,n,total/2+1))/2;
        }
        
    }
};

Code(Python):

class Solution:
    # @return a float
    def findMedianSortedArrays(self, A, B):
        if (len(A) + len(B)) % 2 == 0:
            return (self.fms(A, B, (len(A) + len(B))/2) + self.fms(A, B, (len(A) + len(B))/2 + 1))/2.0
        else:
            return self.fms(A, B, (len(A) + len(B))/2 + 1)
    
    def fms(self, A, B, k):
        if len(A) > len(B):
            return self.fms(B, A, k)
        else:
            if len(A) == 0:
                return B[k-1]
            if k == 1:
                return min(A[0], B[0])
            pa = min(k/2, len(A))
            pb = k - pa
            if A[pa-1] <= B[pb-1]:
                return self.fms(A[pa::], B, k-pa)
            else:
                return self.fms(A, B[pb::], k-pb)
            
        
        

leetcode Question 49: Maximum subarray

Maximum Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.


Analysis:
Classic DP problem.

We can think this problem as this: if the previous sum are +, which is then useful for the current element, or if it is -, why not start the sub array from current element? We can use an int to store the max sum we have got, just scan the whole array, the result is easily found.

Source Code:

class Solution {
public:
    int maxSubArray(int A[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int m=INT_MIN;
        int sum=0;
        for (int i=0;i<n;i++){
            sum = sum>=0?(sum+A[i]):A[i];
            m=max(sum,m);
        }
        return m;
    }
};

leetcode Question 48: Maximum Depth of Binary Tree

Maximum Depth of Binary Tree



Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.


Analysis:

This is an easy problem.
Either DFS (depth first search) or BFS(breadth first search).
Details see source code.
C++:     DFS
Python: BFS

Code(C++):


/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (!root){return 0;}
        else{
            return max(maxDepth(root->right)+1,maxDepth(root->left)+1);
        }
    }
};

Code(Python):

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param root, a tree node
    # @return an integer
    def maxDepth(self, root):
        if root == None:
            return 0
        q = []
        q.append([root, 1])
        res = 0
        while len(q) != 0:
            node, dep = q.pop()
            res = max(res, dep)
            if node.left != None:
                q.append([node.left, dep + 1])
            if node.right != None:
                q.append([node.right, dep + 1])
        return res
            
        
        
        

leetcode Question 47: Maximal Rectangle

Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

Analysis:

This is not an easy problem and the idea is not straightforward.
Since the question requires the area of all ones region, first we can define the region (rectangle) in the matrix. Any region in the matrix has several basic properties:   1 corner point,  width, and length.
Also which corner point it is decide the exact place of the region, here we consider the bottom-right corner point, because we usually scan the matrix from (0,0) to right and down direction. For this problem, we also need to consider the "all ones" requirement, where all the regions are filled with 1s.

We can then have this data structure:
One 2D array(vector) ones[i][j],  where ones[i][j] stores the number of contiguous 1s ended at matrix[i][j], along ith row. e.g.  if matrix[i] = "1011101", then ones[i]=1,0,1,2,3,0,1. This array stores the length of the rectangle, for every possible bottom-right corner point.

Having this two values, next is to find the height of the rectangle, as well as keep the "all ones" requirement.
Start with a corner point [i][j],  since it is the bottom right corner, the rectangle search direction is left and up.
For the left we already have the number of contiguous 1s ones[i][j]. How to get the height?  We need to scan all the values above ones[i][j], it is from i-1 to 0. If meets 0, then stop, else compute the possible rectangle area, and store the max. To compute the area, the minimum length of rectangle should be compared and stores every time.

Details can be found in the code below, which passed all the small and big test cases.

Code(updated 201309):

class Solution {
public:
    int maximalRectangle(vector<vector<char> > &matrix) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int row = matrix.size();
        if (row==0){return 0;}
        int col = matrix[0].size();
        int res=0;
        vector<vector<int>> ones(row,vector<int>(col,0));
            
        for (int i=0;i<row;i++){
            for(int j=0;j<col;j++){
                if (matrix[i][j]=='1'){  
                    if (j==0){ones[i][j]=1;}
                    else{ones[i][j]=ones[i][j-1]+1;}
                }
            }
        }
        
        for (int i=0;i<row;i++){
            for(int j=0;j<col;j++){
                if (ones[i][j]!=0){  
                    int h = i-1;
                    int tmp=ones[i][j];
                    int mini=ones[i][j];
                    while (h>=0){
                        if (ones[h][j]==0){
                            break;
                        }else{
                            if (ones[h][j]<mini){
                                mini = ones[h][j];
                            }
                            if (tmp< mini*(i-h+1)){
                                tmp= mini*(i-h+1); 
                            }
                            h--;
                        }
                    }
                    if (res<tmp){
                        res=tmp;
                    }
                }
            }
        }
        
        return res;
    }
};
 


leetcode Question 46: Longest Valid Parentheses

Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
For "(()", the longest valid parentheses substring is "()", which has length = 2.
Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

Analysis:
Key point is to save the previous result, e.g. ()(), when the second ( is scanned, the result length should add the first pair of ().

Some special cases should be considered:
()()  max = 4
(()() max = 4
()(() max = 2

We want the complexity to be O(n). Thus iteration is from the first element to the last of the string.

Stack is used to stored the character.

If current character is '(', push into the stack.
If current character is ')',
    Case 1:  the stack is empty, reset previous result to zero. Here we renew a pointer to store the earliest index.
    Case 2: the stack is not empty, pop the top element. if the top element is '(' , (which means a () pair is found), then if the poped stack is empty, (which means the previous pairs should be added.), len = current pos - previous pos +1; If the poped stack is not empty, len = current pos- index of stack top element.




Source Code:

class Solution {
public:
    int longestValidParentheses(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (s.size()<2) {return 0;}
        stack<pair<char,int> > st;
        int maxl=0;
        int i=0;
        int t=0;
        while (i<s.size()){            
            if (s[i]=='(') {st.push(make_pair(s[i],i));}
            else{
                if (st.empty()){t=i+1;}
                if (!st.empty()){
                    pair<char,int> tmp = st.top();
                    st.pop();
                    if (tmp.first=='('){
                        if (!st.empty()){maxl=max(maxl,(i-st.top().second));} //key step, i-st.top().second, but not the tmp.second.
                        else{maxl=max(maxl,i-t+1);}
                    }
                }        
            }
            i++;
        }
        return maxl;
    }
};

leetcode Question 45: Longest Substring Without Repeating Characters

Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.


Analysis:
Set two pointers, i,j, scan the string from the start to the end. Set a table to store if the character has occurred.
If s[j] has occurred in S[i..j-1],  compute current length and compare to the max length. Then table[s[i]]=false; i++; If s[j] has not occurred in S[i..j-1], table[s[j]]=true; j++; 


Source code:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if(s.size()==0){return 0;}
        if(s.size()==1){return 1;}
        int i=0;
        int j=0;
        int maxl = 0;
        map<char,bool> table;
        while ( (i<s.size()) && (j<s.size()) ){
            if (table[s[j]]==false){ 
                table[s[j]]=true;
                maxl = max(maxl,j-i+1);
                j++; 
            }else if (table[s[j]]==true){
                maxl = max(maxl,j-i);
                table[s[i]]=false;
                i++;
            }
        }
        return maxl;
    }
};

leetcode Question 44: Longest Palindromic Substring

Longest Palindromic Substring
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.


Analysis:
This is a DP problem. According to http://leetcode.com/2011/11/longest-palindromic-substring-part-i.html
table[i][j] saves if the string start from i ends at j is the Palindromic string.

Initial state:
table[i][i] =  true.
table[i][i+1] = (s[i]==s[i+1]);

State Change:
if s[i]==s[j], table[i][j]=table[i+1][j-1];


Source Code:

class Solution {
public:
    string longestPalindrome(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int n=s.size();
        if(n==0){return "";}
        
        // Using vector might NOT pass the large test, use array instead.
        //vector<vector<bool> > table(n,vector<bool>(n,false));
        
        bool table[1000][1000] = {false};
        
        int maxst=0;
        int maxlen=1;
         
        for (int i=0;i<n;i++){
            table[i][i]=true; 
            maxst=i;
            maxlen=1;
        }
        for (int i=0;i<n-1;i++){
            if (s[i]==s[i+1]){
                table[i][i+1]=true;
                maxst=i;
                maxlen=2;
            }
        }
         
        for (int len=3; len<=n;len++){
            for (int i=0;i<n-len+1;i++){
                int j=i+len-1;
                if (s[i]==s[j] && table[i+1][j-1]){
                    table[i][j]=true;
                    maxst=i;
                    maxlen=len;
                }
            }
        }
        return s.substr(maxst,maxlen);
    }
};

leetcode Question 43: Longest Common Prefix

 Longest Common Prefix


Write a function to find the longest common prefix string amongst an array of strings.

Analysis:

Note that we have an array of strings, where we only need the common prefix, for all these strings.
In other words, for each char in the strings (starts from [0] ), if they are the same, it is a common prefix, we continue check the next index (e.g., [1] ), if they are the same, we continue check the next (e.g., [2])...  The termination conditions are: (1) one string ends, then the longest prefix is the string itself. (2) The chars of same index are not the same, the longest prefix is the sub string from 0 to current index-1.

So the algorithm is pretty simple, scan from the first character, if it is same for all the strings, go to the next character. Return the string until meet the different character.

Code(C++):


class Solution {
public:
    string longestCommonPrefix(vector<string> &strs) {
        if (strs.empty()){return "";}
        if (strs.size()==1){return strs[0];}
        
        for (int i=0;i<strs[0].size();i++){
            for (int j=0;j<strs.size()-1;j++){
                if (i>=strs[j+1].size() || strs[j][i]!=strs[j+1][i]){
                    return strs[j].substr(0,i);
                }
            }
        }
        
        return strs[0];
    }
};


Code (Python):


class Solution:
    # @return a string
    def longestCommonPrefix(self, strs):
        if (len(strs)==0):
            return ""
        if (len(strs)==1):
            return strs[0]
        
        for j in xrange(0,len(strs[0])):
            for i in xrange(0,len(strs)-1):
                if (j>=len(strs[i+1]) or strs[i][j]!=strs[i+1][j]):
                    if j==0:
                        return ""
                    else:
                        return strs[i][0:j]
        return strs[0]
                
                    
        

leetcode Question 42: Letter Combinations of a Phone Number

Letter Combinations of a Phone Number


Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.


Analysis:

This is a simple problem, we can use the DFS to solve it. Details see the source code.

Code(C++):

class Solution {
public:
    void dfs(string digits, string r, map<char,vector<char> > &mp, vector<string> &res){
        if (digits.empty()){
            res.push_back(r);
        }else{
            vector<char> vec = mp[digits[0]];
            for(int i=0;i<vec.size();i++){
                dfs(digits.substr(1),r+vec[i],mp,res);
            }
        }
    }
    vector<string> letterCombinations(string digits) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        map<char,vector<char> > mp;
        vector<char> v;
        int n=2;
        for (char i='a';i<='z';i++){
            v.push_back(i);
            if (i=='c' || i=='f'|| i=='i'|| i=='l'|| i=='o'|| i=='s'|| i=='v'|| i=='z'){
                mp[char(n+'0')]=v;
                n++;
                v.clear();
            }
        }
        
        vector<string> res;
        dfs(digits,"",mp,res);
        return res;
    }
};



Code (Python):


class Solution(object):
    def search(self, digits, k, s, res, mp):
        if k == len(digits):
            res.append(s)
        else:
            for d in mp[digits[k]]:
                self.search(digits, k+1, s+d, res, mp)
            
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        if digits == '':
            return []
        mp = {'1':[], '2':['a','b','c'],'3':['d','e','f'],'4':['g','h','i'],'5':['j','k','l'],
              '6':['m','n','o'],'7':['p','q','r','s'],'8':['t','u','v'],'9':['w','x','y','z'], '0':[]}
        res = []
        self.search(digits, 0, '', res, mp)
        return res

leetcode Question 41: Length of Last Word

Length of last word:

Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.
If the last word does not exist, return 0.
Note: A word is defined as a character sequence consists of non-space characters only.
For example,
Given s = "Hello World",
return 5.

Updated 201309:

class Solution {
public:
    int lengthOfLastWord(const char *s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int sz = strlen(s);
        if (sz==0){return 0;}
        int res=0;
        for (int i=sz-1;i>=0;i--){
            if (s[i]!=' '){res++;}
            else{ if (res>0){return res;} }
        }
        return res;   
    }
};





Old version:
Analysis:
Simple problem, but be careful with the special cases. Such as:  "  " , "  day" ,"day   ",etc.
The basic idea is search from the end to the start, if the current letter is A-Z a-z, count the word, until find the  space or meet the start, return the length.

Source Code:

class Solution {
public:
    int lengthOfLastWord(const char *s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int len = strlen(s);
        if (len==0) {return 0;}
        int res=0;
        bool fl=false;
        while (len>=0){
            if ( (s[len]>='a' && s[len]<='z')||(s[len]>='A' && s[len]<='Z') ){fl=true; res=res+1;}
            if (s[len]==' ' && fl) { return res;}
            len--;
        }
        if (fl) {return res;}
        if (!fl){return 0;}
    }
};

leetcode Question 40: Largest Rectangle in Histogram


Largest Rectangle in Histogram

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
The largest rectangle is shown in the shaded area, which has area = 10 unit.
For example,
Given height = [2,1,5,6,2,3],
return 10.


Analysis:
A simple but time-consuming idea is scan every element find the left bound and right bound.


Source Code:


class Solution {
public:
    int largestRectangleArea(vector<int> &height) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (height.empty()){return 0;}
        vector<int>l(height.size(),0);    
        vector<int>r(height.size(),0);
        
        for (int i = 0; i<height.size();i++){   
            int j=i;
            while((j>0) && (height[i]<=height[j-1])){ j=l[j-1];}
            l[i]=j;
        }
        
        for (int i = height.size()-1;i>=0;i--){   
            int j=i;
            while( (j<height.size()-1) && (height[i]<=height[j+1])){ j=r[j+1];}
            r[i]=j;
        }
            
        int maxa=0;
        for (int i=0;i<l.size();i++){
            maxa = max(maxa,((r[i]-l[i]+1)*height[i]));
        }
        return maxa;
        
    }
};

leetcode Question 39: Jump Game II

Jump Game II


Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)


Analysis:
Using greedy idea, every time get the max length. Details see the code.


Code (C++):


class Solution {
public:
    int jump(int A[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (n==0) {return 0;}
        if (n==1) {return 0;}
        int m=0;
        int i=0;
        int njump=0;
        while (i<n){
            m=max(m,A[i]+i);
            if (m>0) {njump++;}
            if (m>=n-1){return njump;}
            int tmp=0;
            for (int j = i+1; j<=m;j++){
                if (j+A[j]>tmp){
                    tmp=A[j]+j;
                    i=j;
                }
            }
            
        }
        return njump;
    }
};


Code (Python):


class Solution:
    # @param A, a list of integers
    # @return an integer
    def jump(self, A):
        m = 0
        i = 0
        res = 0
        if (len(A)<=1):
            return 0
        while i<len(A):
            m = max(m,A[i]+i)
            if m>0:
                res=res+1
            if m>=len(A)-1:
                return res
            tmp=0
            for j in xrange(i+1,m+1):
                if (j+A[j]>tmp):
                    tmp = j+A[j]
                    i = j
        return res
            
                
            
        

leetcode Question 38: Jump Game

Jump Game


Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.


Analysis:

Note that the A[i] means the maximum jump length. In other words, it is possible that we move j step (<A[i]) when we at A[i], e.g. if A[i]=2, we can move either 1 or 2 steps.

The simple but time-consuming way is O(n^2). Set every future step true according to the A[i]. But this only can pass the small test.

A better idea is use another variable to save the number of steps available. Just a little bit different from the O(n^2) one , see code for more details.



Source code: (C++ : Small)

class Solution {
public:
    bool canJump(int A[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (n==0) {return false;}
        if (n==1) {return true;}
        
        vector<bool>B(n-1,false);
        B[0]=true;
        for (int i=0;i<n;i++){
            if (B[i]==true){
                for (int j=1;j<=A[i];j++){
                    B[i+j]=true;
                }
            }
        }
        return B[n-1];
    }
};

Source code: (C++ : DP)


class Solution {
public:
    bool canJump(int A[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (n==0) {return false;}
        if (n==1) {return true;}
        
        int m=0;
        for (int i=0;i<n;i++){
            if (i<=m){
             m=max(m,A[i]+i);
             if (m>=n-1){return true;}
            }
        }
        return false;
    }
};


Code (Python):


class Solution:
    # @param A, a list of integers
    # @return a boolean
    def canJump(self, A):
        m = 0
        for i in xrange(0,len(A)):
            if i<=m:
                m = max(A[i]+i,m)
                if m>=len(A)-1:
                    return True
        return False
            
            
        

leetcode Question 37: Interleaving String


Interleaving String
Given s1s2s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc",
s2 = "dbbca",
When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.



Analysis (Updated 201309):

First we can consider this as a recursive problem.
If  s3[i1+i2+1] == s1[i1+1], search(i1+1,i2)
If  s3[i1+i2+1] == s2[i2+1], search(i1,i2+1)
until end. However, this can only pass the small test cases, but failed on the large test cases.

So we need to think of the dynamic programming (DP), which usually have much less complexity. In this problem, a 2D DP is more suitable.  As usual, the typical way of solving dp is to find the state, and the optimal function. Here, the state can be considered as: A[i][j], which means S3[i+j] can be formed by S1[i] and S2[j] (for simplicity here string starts from 1, in the code we need to deal with that string starts from 0).

So, we have the optimal function:
  A[i][j] =   (s3[i+j]==s1[i]  && match[i-1][j])  || (s3[i+j] ==s2[j] && match[i][j-1])

Given the state and the optimal function, we also need to be careful with the initialization. Details see the code below.

Code(Updated 201312):



class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
         int n1 = s1.size();
        int n2 = s2.size();
        vector<vector<bool> > A(n1+1,vector<bool>(n2+1,false));
        if (n1+n2!=s3.size()){return false;}
        if (s1.empty()&&s2.empty()&&s3.empty()){return true;}
         
        A[0][0]=true;    
        for (int i=1;i<=n1;i++){
            if (s1[i-1]==s3[i-1] && A[i-1][0]){A[i][0]=true;}
        }
        for (int i=1;i<=n2;i++){
            if (s2[i-1]==s3[i-1] && A[0][i-1]){A[0][i]=true;}
        }
                 
        for (int i=1;i<=n1;i++){
            for (int j=1;j<=n2;j++){
                A[i][j]= (A[i][j-1] && (s2[j-1]==s3[i+j-1])) || (A[i-1][j]&& (s1[i-1]==s3[i+j-1]));   
            }
        }
        return A[n1][n2];
    }
};

leetcode Question 36: Integer to Roman


Integer to Roman
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.


Analysis:
There is no standard way of transferring integer to Roman, this problem may have multiple ways.
Here is one solution but may not pass all the test.

Source Code:

class Solution {
public:
    string intToRoman(int num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function    
        int n_M = int(num/1000);
        num = num%1000;
        int n_D = int(num/500);
        num = num%500;
        int n_C = int(num/100);
        num = num%100;
        int n_L = int(num/50);
        num = num%50;
        int n_X = int(num/10);
        num = num%10;
        int n_V = int(num/5);
        num = num%5;
        int n_I = int(num/1);
        
        return string(n_M,'M')+string(n_D,'D')+string(n_C,'C')+string(n_L,'L')+string(n_X,'X')+string(n_V,'V')+string(n_I,'I');
        
    }
};


This code is another way of represent integer to roman, and this one can pass all the test:
According to the rule (from wiki):

  • A number written in Arabic numerals can be broken into digits. For example, 1903 is composed of 1 (one thousand), 9 (nine hundreds), 0 (zero tens), and 3 (three units). To write the Roman numeral, each of the non-zero digits should be treated separately. In the above example, 1,000 = M, 900 = CM, and 3 = III. Therefore, 1903 = MCMIII.[4]
  • The symbols "I", "X", "C", and "M" can be repeated three times in succession, but no more. (They may appear more than three times if they appear non-sequentially, such as XXXIX.) "D", "L", and "V" can never be repeated.[5][6]
  • "I" can be subtracted from "V" and "X" only. "X" can be subtracted from "L" and "C" only. "C" can be subtracted from "D" and "M" only. "V", "L", and "D" can never be subtracted[6]
  • Only one small-value symbol may be subtracted from any large-value symbol.[7]



class Solution {
public:
    string intToRoman(int num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function    
        string res;
        int n_M = int(num/1000);
        res += string(n_M,'M');
        num = num%1000;
        int n_C = int(num/100);
        if (n_C!=0){
        if (n_C<=3){res += string(n_C,'C');}
        if (n_C==4){res += "CD";}
        if (n_C>=5 && n_C<=8){ res+="D";res += string(n_C-5,'C');}
        if (n_C==9){res += "CM";}
        }
        num = num%100;
        int n_X = int(num/10);
        if (n_X!=0){
        if (n_X<=3){res += string(n_X,'X');}
        if (n_X==4){res += "XL";}
        if (n_X>=5 && n_X<=8){res+="L"; res += string(n_X-5,'X'); }
        if (n_X==9){res += "XC";}
        }
        num = num%10;
        int n_I = int(num/1);
        if (n_I!=0){
            if (n_I<=3){res += string(n_I,'I');}
            if (n_I==4){res += "IV";}
            if (n_I>=5 && n_I<=8){res+="V"; res += string(n_I-5,'I'); }
            if (n_I==9){res += "IX";}
        }
        return res;
    }
};