Monday, February 29, 2016

[LeetCode] 11. Container With Most Water

Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.


1. Two pointer scan with greedy.

public class Solution {
    public int maxArea(int[] height) {
        int len = height.length;
        if(0 == len)
            return 0;

        int res = -1;
            
        int i = 0;
        int j = len-1;
        
        while(i < j){
            int hI = height[i];
            int hJ = height[j];
            
            int water = Math.min(hI, hJ)*(j - i);
            if(water > res){
                res = water;
            }
            
            if(hI < hJ){
                i++;
            }else{
                j--;
            }
        }
        
        return res;
    }
}

Tuesday, February 23, 2016

[LeetCode] 7. Reverse Integer My

Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321

1. Special handling of overflow.

public class Solution {
    public int reverse(int x) {
        if (0 == x)
            return 0;
        boolean n = false;
        if (x < 0){
            x = x * -1;
            n = true;
        }
        int of = Integer.MAX_VALUE / 10;
        
        int res = 0;
        while(x > 0){
            if(res <= of){
                res *= 10;
                if(Integer.MAX_VALUE - res > x % 10){
                    res += x % 10;
                }
                x /= 10;
            }
            else{
                return 0;
            }
        }
        return n?res*-1:res;
        
    }
}

[LeetCode] 9. Palindrome Number











1. Wrong code. 1000021 --> true. Once 1000000 and 1 is subtract, only 2 left.
Should get the number of digits first.

public class Solution {
    public boolean isPalindrome(int x) {
        
        if(0 == x)
            return true;
        
        if(x < 0)
            return false;
        
        while(x >= 10){    
            int r = x % 10;
        
            int l = x;
            int s = 1;
            while(l >= 10){
                l /= 10;
                s *= 10;
            }
            s *= l;
            
            if(l != r)
                return false;
            
            x -= s;
            x /= 10;
        }
        
        return true;
        
    }
}


[LeetCode] 10. Regular Expression Matching

Implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.

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", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true


1. DP, code is not elegant enough. Will improve later. Judge the way the code end is an issue, at the boader charAt will not work.

public class Solution {
    
    public int isMatchAux(String s, String p, int indexS, int indexP, int[][] dp){
        int lenS = s.length();
        int lenP = p.length();
        
        if(lenS < indexS || lenP < indexP){
            return -1;
        }
        
        if(0 != dp[indexS][indexP]){
            return dp[indexS][indexP];
        }
        
        if(lenS == indexS && lenP == indexP){
            dp[indexS][indexP] = 1;
            return dp[indexS][indexP];
        }else if(lenS == indexS && indexP < lenP -1 && '*' == p.charAt(indexP + 1)){
            dp[indexS][indexP] = isMatchAux(s, p, indexS, indexP + 2, dp);
            return dp[indexS][indexP];
        }else if(lenS == indexS || lenP == indexP){
            dp[indexS][indexP] = -1;
            return dp[indexS][indexP];
        }
        
        
        char cs = s.charAt(indexS);
        char cp = p.charAt(indexP);
        
        if(0 == dp[indexS][indexP]){
            
            boolean ret = false;
            
            if(indexP < lenP -1 && '*' == p.charAt(indexP + 1) ){
                ret = ret || isMatchAux(s, p, indexS, indexP + 2, dp) == 1;
                if('.' == cp || cs == cp){
                    ret = ret || isMatchAux(s, p, indexS + 1, indexP, dp) == 1;
                    ret = ret || isMatchAux(s, p, indexS + 1, indexP+2, dp) == 1;
                }
            }else if('.' == cp || cs == cp){
                ret = isMatchAux(s, p, indexS + 1, indexP + 1, dp) == 1;
            }
            
            dp[indexS][indexP] = ret ? 1: -1;
        
        }
        
        return dp[indexS][indexP];
    }
    
    public boolean isMatch(String s, String p) {
        int lens = s.length();
        int lenp = p.length();
        
        int[][] dp = new int[lens+1][lenp+1];
        
        return isMatchAux(s, p, 0, 0, dp) == 1? true: false;
    }
}

Saturday, February 20, 2016

[leetcode] 8. String to Integer (atoi)


Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
1.  Very boring problem. Not sure possible inputs before coding.
https://github.com/csehao/LeetCode/blob/master/Java/StringtoInteger.java

public class Solution {
    public int myAtoi(String str) {
        int len = str.length();
        int res = 0;
        boolean pn = true;
        boolean hasValue = false;
        boolean pnvalid = false;
        
        int md10 = Integer.MAX_VALUE/10;
        int md10tail = Integer.MAX_VALUE - md10;
        // It is necessary to Integer.MIN_VALUE as well. Omitted here.

        int nmd10 = Integer.MAX_VALUE/10;
        
        for(int i = 0; i < len; ++i){
            Character c = str.charAt(i);
            if('+' == c){
                if(pnvalid == true)
                    return 0;
                pn = true;
                pnvalid = true;
            }else if('-' == c){
                if(pnvalid == true)
                    return 0;
                pn = false;
                pnvalid = true;
            }else if(Character.isDigit(c)){
                
                if(res > md10){
                    return pn?Integer.MAX_VALUE:Integer.MIN_VALUE;    
                }
                res*= 10;
                int value = (int)(Character.getNumericValue(c));
                if(Integer.MAX_VALUE - value < res)
                    return pn?Integer.MAX_VALUE:Integer.MIN_VALUE;
                res+= value;
                hasValue = true;
            }else if(c == ' '){
                if(false == hasValue && pnvalid == false)
                    continue;
                    
                if(hasValue || pnvalid == true){
                    return pn?res:-1*res; 
                }
                
            }else{
                if(hasValue){
                    return pn?res:-1*res;
                }
                else{
                    return 0;
                }
            }
        }
        
        return pn?res:-1*res;
        
    }
}


It is necessary to test the mod behavior under positive and negative values.


[LeetCode] 6. 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".



1. Element manipulation.
 Special boarder condition on first row and last row
 Special boarder condition on 1 row.
 Alternative increment, see initial increment to the second step first, will be changed to step 1.
 Better way is to setup index,

public class Solution {
    public String convert(String s, int numRows) {
        int len = s.length();
        
        StringBuilder sb = new StringBuilder();
        if(0 == len)
            return sb.toString();
        
        if(1 == numRows){
            return s;
        }
        
        for(int j = 0; j < numRows; ++j){
            
            int d1 = 2*(numRows - 1 - j);
            int d2 = 2*j;
            
            if(0 == d1){
                for(int i = j; i < len; i += d2){
                    sb.append(s.charAt(i));
                }
            }
            else if(0 == d2){
                for(int i = j; i < len; i += d1){
                    sb.append(s.charAt(i));
                }
            }
            else{
                int d = d2;
                for(int i = j; i < len; i += d){
                    sb.append(s.charAt(i));
                    if(d == d1)
                        d = d2;
                    else
                        d = d1;
                }
            }
            
        }
        
        return sb.toString();
        
    }
}
2. The following code works as well, the condition of the last row matches with middle rows, special handling of the first row, first element is OK.

public class Solution {
    public String convert(String s, int numRows) {
        int len = s.length();
        
        StringBuilder sb = new StringBuilder();
        if(0 == len)
            return sb.toString();
        
        sb.append(s.charAt(0));
        
        if(1 == numRows){
            return s;
        }
        
        for(int j = 0; j < numRows; ++j){
            int d1 = 2*(numRows - 1 - j);
            int d2 = 2*j;
            
            int d = d2;
            
            for(int i = j; i < len; i += d){
                if(0 != d){
                    sb.append(s.charAt(i));
                }
                if(d == d1)
                    d = d2;
                else
                    d = d1;
            }
        }
        
        return sb.toString();
        
    }
}
3. A more efficient code It turns out, set up a variable to judge the past increment value seems to be the leanest code. Might not be the most efficient one. It is similar to set a prehead in list manipulation. From somewhere before the list, from somewhere before the array.

public class Solution {
    public String convert(String s, int numRows) {
        int len = s.length();
        
        StringBuilder sb = new StringBuilder();
        if(0 == len)
            return sb.toString();
        
        if(1 == numRows){
            return s;
        }
        
        for(int j = 0; j < numRows; ++j){
            
            int d1 = 2*(numRows - 1 - j);
            int d2 = 2*j;

            int[] inc = new int[2];
            inc[0] = d1;
            inc[1] = d2;
                
            int index = 0;
            int add = -1;
            for(int i = j; i < len; i += inc[index++%2]){
                if(0 != add)
                    sb.append(s.charAt(i));
                add = inc[index%2];
            }
        }
        
        return sb.toString();
        
    }
}

[LeetCode] 5. 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.

1. DP, O(N^2) complexity.

https://github.com/csehao/LeetCode/blob/master/Java/LongestPalindrome.java

public class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        
        StringBuilder sb = new StringBuilder();
        if(0 == len)
            return sb.toString();
            
        boolean[][] dp = new boolean[1001][1001];
        
        int l = 0;
        int u = 1;
        
        for(int i = 0; i < len; ++i){
            dp[i][i+1] = true;
        }
        
        for(int i = 0; i < len-1; ++i){
            if(s.charAt(i) == s.charAt(i+1)){
                dp[i][i+2] = true;
                l = i;
                u = i+2;
                
            }
            else{
                dp[i][i+2] = false;
            }
        }

        for(int d = 3; d <= len; ++d){
            for(int i = 0; i<=len-d; ++i){
                if(s.charAt(i) == s.charAt(i+d-1)){
                    dp[i][i+d] = dp[i+1][i+d-1];
                    if(dp[i][i+d] == true){
                        l = i;
                        u = i+d;
                    }
                }
                else{
                    dp[i][i+d] = false;
                }
            }
        }
        
        return s.substring(l, u);
        
    }
}