leetcode Quesion 79: Remove Duplicates from Sorted List

Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.
Analysis:
This problem is a classic one using the pointers.
Idea is just link the duplicates to the next element.

e.g.            1->1->1->2->3->4
1st step      1 ----->1->2->3->4
2nd step     1 --------->2->3->4


Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (head==NULL){return NULL;}
        if (head->next==NULL){return head;}
        ListNode* list = head;
        while (head->next!=NULL){
            
            if (head->next->val==head->val){
                head->next=head->next->next;
            }else{
                head = head->next;
            }
        }
        return list;
    }
};

leetcode Question 78: Remove Duplicates from Sorted Array II

Remove Duplicates from Sorted Array II

Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?
For example,
Given sorted array A = [1,1,1,2,2,3],
Your function should return length = 5, and A is now [1,1,2,2,3].

Analysis:
Just like the idea of previous problem (see Remove Duplicates from Sorted Array)
But add another flag store the number of duplicated elements.
Details can be seen in code.

Code:

class Solution {
public:
    int removeDuplicates(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 A[0];}
        int pre=A[0];
        int pos = 0;
        int m=n;
        int i=1;
        int count =0;
        while (i<m){
            if (A[i]==pre){
                count ++;
                if (count <2){
                    i++;
                }else{
                    m=m-1;
                    for (int j=pos+1; j<m;j++){
                        A[j]=A[j+1];
                    }
                }
            }else{
                count =0;
                pre=A[i];
                pos=i;
                i++;
            }        
        }
        return m;
    }
};

leetcode Question 77: Remove Duplicates from Sorted Array

Remove Duplicates from Sorted Array

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
For example,
Given input array A = [1,1,2],
Your function should return length = 2, and A is now [1,2].

Analysis:

The trick is given array is already sorted, which means the duplicated elements are all together. e.g.(1,1,2,2,3,4,5,5,5,6,7,7,8,9)

From the 1st element, store current element value(from A[0]), if the current element == stored value, put all the elements one step back. e.g. A[i]=A[i+1]; then change the length of the array.


Update 201402:
Code:

class Solution {
public:
    int removeDuplicates(int A[], int n) {
        if (n<2){return n;}
        
        //Forward scan
        /*int i=1;        
        int pre=A[0];
        int len = n;
        while (i<len){
            if (pre==A[i]){
                for(int j=i;j<len;j++){A[j]=A[j+1];}
                len--;
            }else{
                pre = A[i];
                i++;
            }
        }*/
        
        // Backward Scan
        int i=n-2;
        int pre = A[n-1];
        int len = n;
        while (i>=0){
            if (pre==A[i]){
                for (int j=i;j<len;j++){A[j]=A[j+1];}
                len--;
                i--;
            }else{
                pre=A[i];
                i--;
            }
        }
        
        return len;
    }
};

leetcode Question 120: Valid Parentheses

Valid Parentheses

Given a string containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.
The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.

Analysis:
Idea is not complex.
Use a stack to store the chars, scan from the 1st to the last char in string s.
( [ { are free to push in the stack.
When meets ) if stack top is (, then pop (.
When meets ] if stack top is [, then pop [.
When meets } if stack top is {, then pop {.
Otherwise return false

In the end, if the stack is empty, return true. (to handle "()(" case )


Code:

class Solution {
public:
    bool isValid(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        stack<char> st;
        for (int i=0;i<s.size();i++){                    
            if ((s[i]=='(') ||(s[i]=='[') ||(s[i]=='{')) {st.push(s[i]);}
            else{   
                if (st.empty()){return false;}
                if ((s[i]==')') && (st.top()!='(')) {return false;}
                if ((s[i]=='{') && (st.top()!='}')) {return false;}
                if ((s[i]=='[') && (st.top()!=']')) {return false;}
                st.pop();
            }
            
        }
        return st.empty();
    }
};

leetcode Question 121: Valid Sudoku

Valid Sudoku

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'.


Analysis:
This question is so simple.
As the Sudoku has fixed size of board (9x9), the check procedure can be solved using just "for loop"
1. Check the rows and columns respectively, a mark array is used to check the numbers.
2. Check the 3x3 blocks, also using a mark array.


Code(updated 201309):

class Solution {
public:
    bool isValidSudoku(vector<vector<char> > &board) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        map<char, bool> row;
        map<char, bool> col;
        map<char, bool> block;
        
        for (int i=0;i<9;i++){
            col.clear();
            row.clear();
            for (int j=0;j<9;j++){
                if (board[i][j]!='.'){
                    if (col[board[i][j]]){
                        return false;
                    }else{
                        col[board[i][j]]=true;
                    } 
                }
                if (board[j][i]!='.'){
                    if (row[board[j][i]]){
                        return false;
                    }else{
                        row[board[j][i]]=true;
                    } 
                }
            }
        }
                
        for (int ii=0;ii<9;ii=ii+3){
            for (int jj=0;jj<9;jj=jj+3){
                block.clear();
                for (int i=ii;i<ii+3;i++){
                    for (int j=jj;j<jj+3;j++){
                        if (board[i][j]!='.'){
                            if (block[board[i][j]]){
                                return false;
                            }else{
                                block[board[i][j]]=true;
                            } 
                        }
                    }
                }        
            }
        }
        
        return true;
    }
};



Code(old version):

class Solution {
public:
    bool isValidSudoku(vector<vector<char> > &board) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
                
                
        //Check rows and columns        
        for (int i=0;i<9;i++){
            vector<bool>marki(10,false);
            vector<bool>markj(10,false);
            for (int j=0;j<9;j++){
                if (board[i][j]!='.'){
                    if (marki[int(board[i][j]-'0')]==false){marki[int(board[i][j]-'0')]=true;}
                    else {return false;}
                }
                if (board[j][i]!='.'){
                    if (markj[int(board[j][i]-'0')]==false){markj[int(board[j][i]-'0')]=true;}
                    else {return false;}
                }
            }
        }
            
        //Check 3x3 blocks
        for (int i=0;i<9;i+=3){
            for (int j=0;j<9;j+=3){
                vector<bool>mark(10,false);
                for (int p=0;p<3;p++){
                    for (int q=0;q<3;q++){
                        if (board[i+p][j+q]!='.'){
                           if (mark[int(board[i+p][j+q]-'0')]==false) {mark[int(board[i+p][j+q]-'0')]=true;}
                            else {return false;}
                        }        
                    }
                }
                
                
            }
        }
        return true;
        
    }
};

leetcode Question 122: Validate Binary Search Tree

Validate Binary Search Tree

Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
Example 1:
2
/ \
1 3
Binary tree [2,1,3], return true.
Example 2:
1
/ \
2 3
Binary tree [1,2,3], return false.

Analysis:

The simplest is way of this problem is to utilize the property of the BST, of which the inorder traversal is sorted by ascending order. We could just save the inorder results into one vector, and a check will solve the problem.

A slight more efficient soluiton is to save the previous node in our recursion, by simply checking the currnt node with previous node in each traversal, we could find if the tree is a BST or not.

Code(C++):

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void inorder(TreeNode* root, TreeNode* &prev, bool &res){
if (!root || !res) {return;}
inorder(root->left, prev, res);
if (prev && root->val <= prev->val ){
res = false;
return;
}
prev = root;
inorder(root->right,prev, res);
}
bool isValidBST(TreeNode* root) {
bool res = true;
TreeNode* prev = NULL;
inorder(root, prev, res);
return res;
}
};

Code (Python):

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def inorder(self, root, prev, res):
if not root or not res:
return
self.inorder(root.left, prev, res)
if prev[0] and root.val <= prev[0].val:
res[0] = False
return
prev[0] = root
self.inorder(root.right, prev, res)
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
prev = [None]
res = [True]
self.inorder(root, prev, res)
return res[0]

leetcode Question 123: Wildcard Matching

Wildcard Matching


Implement wildcard pattern matching with support for '?' and '*'.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false

Analysis:


For each element in s
If *s==*p or *p == ? which means this is a match, then goes to next element s++ p++.
If p=='*', this is also a match, but one or many chars may be available, so let us save this *'s position and the matched s position.
If not match, then we check if there is a * previously showed up,
       if there is no *,  return false;
       if there is an *,  we set current p to the next element of *, and set current s to the next saved s position.

e.g.

abed
?b*d**

a=?, go on, b=b, go on,
e=*, save * position star=3, save s position ss = 3, p++
e!=d,  check if there was a *, yes, ss++, s=ss; p=star+1
d=d, go on, meet the end.
check the rest element in p, if all are *, true, else false;

Note that in char array, the last is NOT NULL, to check the end, use  "*p"  or "*p=='\0'".




Code(C++):


class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        
        const char* star=NULL;
        const char* ss=s; 
        while (*s){
            if ((*p=='?')||(*p==*s)){s++;p++;continue;}
            if (*p=='*'){star=p++; ss=s;continue;}
            if (star){ p = star+1; s=++ss;continue;}
            return false;
        }
        while (*p=='*'){p++;}
        return !*p;
    }
};


Code (Python):


class Solution:
    # @param s, an input string
    # @param p, a pattern string
    # @return a boolean
    def isMatch(self, s, p):
        s_cur = 0;
        p_cur= 0;
        match = 0;
        star = -1;
        while s_cur<len(s):
            if p_cur< len(p) and (s[s_cur]==p[p_cur] or p[p_cur]=='?'):
                s_cur = s_cur + 1
                p_cur = p_cur + 1
            elif p_cur<len(p) and p[p_cur]=='*':
                match = s_cur
                star = p_cur
                p_cur = p_cur+1
            elif (star!=-1):
                p_cur = star+1
                match = match+1
                s_cur = match
            else:
                return False
        while p_cur<len(p) and p[p_cur]=='*':
            p_cur = p_cur+1
            
        if p_cur==len(p):
            return True
        else:
            return False
                
                

leetcode Question 124: Word Search

Word Search

Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
For example,
Given board =
[
  ["ABCE"],
  ["SFCS"],
  ["ADEE"]
]
word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.

Analysis:
The idea of this question is as follows:
(1) Find the 1st element of the word in the board.
(2) For each position found where the 1st element lies, recursively do:
           (i) Search the around cell to see if the next element exists. (4 directions: (i-1,j),(i+1,j),(i,j-1),(i,j+1) )
           (ii) If the word ends, return true.
(3) Return false if no matching found.
Note: A mask matrix is needed to store the positions where have already been visited. Details can be found in code.


Code:

class Solution {
public:

    bool search(vector<vector<char> > &board, int i,int j,string str,vector<vector<bool> > &mask){
        if (str.size()==0){return true;}
        else{
            if ((i>0)&&(board[i-1][j]==str[0])&&(mask[i-1][j]==false)){
                mask[i-1][j]=true;
                if (search(board,i-1,j,str.substr(1),mask)){
                    return true;
                }
                mask[i-1][j]=false;
            }
            if ((i<board.size()-1)&&(board[i+1][j]==str[0])&&(mask[i+1][j]==false)){
                mask[i+1][j]=true;
                if (search(board,i+1,j,str.substr(1),mask)){
                    return true;
                }
                mask[i+1][j]=false;
            }
            if ((j>0)&&(board[i][j-1]==str[0])&&(mask[i][j-1]==false)){
                mask[i][j-1]=true;
                if (search(board,i,j-1,str.substr(1),mask)){
                    return true;
                }
                mask[i][j-1]=false;
            }
            if ((j<board[0].size()-1)&&(board[i][j+1]==str[0])&&(mask[i][j+1]==false)){
                mask[i][j+1]=true;
                if (search(board,i,j+1,str.substr(1),mask)){
                    return true;
                }
                mask[i][j+1]=false;
            }
        }
        return false;
    }

    bool exist(vector<vector<char> > &board, string word) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (word.size()==0) {return false;}
            
        for (int i=0;i<board.size();i++){
            for (int j=0;j<board[0].size();j++){
                if (word[0]==board[i][j]){
                    if (word.size()==1) {return true;}
                    else{
                        vector<vector<bool> > mask(board.size(),vector<bool>(board[0].size(),false));
                        mask[i][j]=true;
                        if (search(board,i,j,word.substr(1),mask)){
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
};

leetcode Question 125: ZigZag Conversion

ZigZag Conversion:


The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
P   A   H   N
A P L S I I G
Y   I   R
And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".


Analysis:
The idea is straightforward. Use a 2-D vector storing the zigzag sequence, for every element in the string, put it into proper position. Then output.
There are two major steps to put element into its position:
    (1).  Write # of nRows chars into the same column. like " | "
    (2).  Write # of nRows-2 chars into different column and rows in reverse diagonal order.   like " / ".

e.g.
Input: PAYPALISHIRING

2D vector:
0  1  2 3 4  5 6  7
-------------------
0 | P         I         N
1 | A     L S     I  G
2 | Y  A   H  R
3 | P         I

(updated 201309):

Note:  "ABCD" is    A  C
                               | / |
                              B  D

Code:

class Solution {
public:
    string convert(string s, int nRows) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function    
        vector<string> zz(nRows,"");
        if (nRows==1){return s;}
        
        int i=0; //for string 
        int r=0; //for zz vector
        bool zig = false; // if s[i] is in "/" or "|" direction
        while (i<s.size()){
            if (r<nRows && !zig){
                zz[r]+=s[i];
                r++;
                i++;
            }else{
                if (!zig){
                    zig=true;
                    r--;
                }else{
                    r--;
                    zz[r] = zz[r]+s[i];
                    if (r==0){zig=false;r++;}
                    i++;
                }
            }
        }
        string res; //get result;
        for (int i=0;i<zz.size();i++){
            for (int j=0;j<zz[i].size();j++){
                    res = res+ zz[i][j];
            }
        }
        return res;
    }
};





(old version)Code:

class Solution {
public:

    string printStr(vector<vector<char> > &t, int col,int nRow){
        string str="";
            for (int j=0;j<nRow;j++){
                for (int i =0; i<=col;i++){
                if (t[j][i]!='#'){
                    str = str+ t[j][i];
                }
            }
        }
        return str;
    }
    
    string convert(string s, int nRows) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function    
        if ((nRows<=0) || (s.size()==0)){return "";}
        if (nRows==1) {return s;}
        if (nRows>=s.size()){return s;}
        int k=s.size();
        vector<vector<char> > t(nRows,vector<char>(k,'#'));
        int len = s.size();
        int col = 0;
        int row = 0;
        int count = 0;
        while(count < len){
            if (row<nRows){
                t[row][col]=s[count];
                row++;
                count++;
            }else{
                col++;
                for (int j = nRows-2; j>=1;j--){
                    t[j][col]=s[count];
                    count ++;
                    if (count>=len){ return  printStr(t,col,nRows);}
                    col++;
                }
                row = 0;
            }
        }
        return printStr(t,col,nRows);
    }
};