显示标签为“string”的博文。显示所有博文
显示标签为“string”的博文。显示所有博文

2015年10月26日星期一

Valid Anagram leetcode

Given two strings s and t, write a function to determine if t is an anagram of s.
For example,
s = "anagram", t = "nagaram", return true.
s = "rat", t = "car", return false.

public class Solution {
    public boolean isAnagram(String s, String t) {
        int[] tem = new int[26];
        for (int i = 0; i < s.length(); i++) {
            tem[s.charAt(i) - 'a']++;
        }
        for (int i = 0; i < t.length(); i++) {
            tem[t.charAt(i) - 'a']--;
        }
        for (int str : tem) {
            if (str != 0) {
                return false;
            }
        }
        return true;
    }
}

2015年10月14日星期三

Fraction to Recurring Decimal leetcode

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.
If the fractional part is repeating, enclose the repeating part in parentheses.
For example,
  • Given numerator = 1, denominator = 2, return "0.5".
  • Given numerator = 2, denominator = 1, return "2".
  • Given numerator = 2, denominator = 3, return "0.(6)".

用hashmap来记录余数, value存余数所得的商的位置, 当余数重复出现时候就能找到循环的数字的范围了
为了防止溢出要用long, 对于abs一定要取long得abs, 因为abs(Integer.MIN_VALUE)是他本身
public class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        if (numerator == 0 || denominator == 0) {
            return "0";
        }
        
        String res = "";
        if ((numerator < 0 & denominator > 0) || (numerator > 0 && denominator < 0)) {
            res += "-";
        }
        long num = numerator, den = denominator;
        num = Math.abs(num);
        den = Math.abs(den);
        long ans = num / den;
        long rem = (num % den) * 10;
        res += ans;
        if (rem == 0) {
            return res;
        }
        res += ".";
        HashMap<Long, Integer> map = new HashMap<Long, Integer>();
        while (rem != 0) {
            if (map.containsKey(rem)) {
                int index = map.get(rem);
                String part1 = res.substring(0, index);
                String part2 = res.substring(index, res.length());
                res = part1 + "(" +part2 + ")";
                return res;
            } else {
                map.put(rem, res.length());
                res += rem / den;
                rem = rem % den * 10;
            }
        }
        return res;
        
    }
}

2015年10月13日星期二

Compare Version Numbers leetcode

Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.
You may assume that the version strings are non-empty and contain only digits and the . character.
The . character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.
Here is an example of version numbers ordering:
0.1 < 1.1 < 1.2 < 13.37
这道题的trick在于 version 1.1.20 和1.1.2 是相同的.
这里用到String.split() 来按照"." 把string 分成array 
String.split() accepts a regular expression (regex for short) and dot is a special char in regexes. It means "match all chars except newlines". So you must escape it with a leading backslash. But the leading backslash is a special character in java string literals. It denotes an escape sequence. So it must be escaped too, with another leading backslash. Like this:
fileName.split("\\.");

public class Solution {
    public int compareVersion(String version1, String version2) {
        String[] arr1 = version1.split("\\.");
        String[] arr2 = version2.split("\\.");
        int i = 0;
        for (; i < arr1.length && i< arr2.length; i++) {
            if (Integer.parseInt(arr1[i]) < Integer.parseInt(arr2[i])) {
                return -1;
            } else if (Integer.parseInt(arr1[i]) > Integer.parseInt(arr2[i])) {
                return 1;
            }
        }
        while (i < arr1.length) {
            if (Integer.parseInt(arr1[i++]) > 0) {
                return 1;
            }
        }
        while (i < arr2.length) {
            if (Integer.parseInt(arr2[i++]) > 0) {
                return -1;
            }
        }
     
        return 0;
    }
}

2015年10月6日星期二

Read N Characters Given Read4 II - Call multiple times leetcode

The API: int read4(char *buf) reads 4 characters at a time from a file.
The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file.
By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file.
Note:
The read function may be called multiple times.

/* The read4 API is defined in the parent class Reader4.
      int read4(char[] buf); */

public class Solution extends Reader4 {
    Queue queue = new LinkedList();
    public int read(char[] buf, int n) {
        int i = 0;
        while (i < n && !queue.isEmpty()) {
            buf[i] = queue.poll();
            i++;
        }
        for (; i < n; i+= 4) {
            char[] tem = new char[4];
            int len = read4(tem);
            if (len > n - i) {
                System.arraycopy(tem, 0, buf, i, n - i);
                for (int j = n - i; j < len; j++) {
                    queue.offer(tem[j]);
                }
            } else {
                System.arraycopy(tem, 0, buf, i, len);
            }
            if (len < 4) {
                return Math.min(len + i, n);
            }
        }
        return n;
    }
}

Read N Characters Given Read4 leetcode

The API: int read4(char *buf) reads 4 characters at a time from a file.
The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file.
By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file.
Note:
The read function will only be called once for each test case.
每次read4读到的字符放入一个数组里, 然后把数组里面的值拷贝到buffer内
concer case1: 在i = n - 1 时如果我们的read4 读了多个字符(长度len) , 那么我们存入buf数组中的个数应为Math.min(n - i, len)
case2: 如果len < 4 说明数组已经读完了 这时候返回的长度应该是Math.min(i + len, n)
public class Solution extends Reader4 {

    public int read(char[] buf, int n) {
        char[] tem = new char[4];
        int index = 0;
        for (int i = 0; i < n; i+= 4) {
            int len = read4(tem);
            for (int j = 0; j < Math.min(len, n - i); j++) {//case1
                buf[index++] = tem[j];
            }
            if (len < 4) {//case 2
                return Math.min(i + len, n);
            }
        }//如果循环内没有返回 说明读取字符数为4的倍数
        return n;
    }
}

One Edit Distance leetcode

Given two strings S and T, determine if they are both one edit distance apart.
首先如果字符相差超过一个, 必然为false
one edit 分为三种情况
s = abcde
t1 = abcdex
t2 = abcxe
t3 = abcxde
这三种情况都为true
time O(n) space O(1)
public class Solution {
    public boolean isOneEditDistance(String s, String t) {
        int m = s.length();
        int n = t.length();
        if (m > n) {
            return isOneEditDistance(t, s);
        }
        if (n - m > 1) {
            return false;
        }
        int i = 0;
        while (i < m && s.charAt(i) == t.charAt(i)) {
            i++;
        }
        if (i == m) {//case t: abcdex
            return n - m == 1;
        }
        if (m == n) {//case t: abcxd
            i++;
            while (i < m && s.charAt(i) == t.charAt(i)) {
                i++;
            }
        }
        if (n - m == 1) {// case t: abcxde
            while (i < m && s.charAt(i) == t.charAt(i + 1)) {
                i++;
            }
        }
        return i == m;
    }
}

2015年10月1日星期四

Reverse Words in a String II leetcode

Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters.
The input string does not contain leading or trailing spaces and the words are always separated by a single space.
For example,
Given s = "the sky is blue",
return "blue is sky the".
三步翻转法, 先把s = the sky is blue ---> eulb si yks eth
然后 挨个单词再翻转一遍. 
对于前面的单词碰到空格就翻转 对于最后一个单词当指针走到最后一个字符时候翻转

public class Solution {
    public void reverseWords(char[] s) {
        if (s == null || s.length == 0) {
            return;
        }
        rotate(s, 0, s.length - 1);
        int last = 0;
        for (int i = 0; i < s.length; i++) {
            if ( s[i] == ' ') {
                rotate(s, last, i - 1);
                last = i + 1;
            }
            if (i == s.length - 1) {
                rotate(s, last, i);
            }
        }
    }
    public void rotate(char[] s, int left, int right) {
        if (s == null ||s.length == 0 || left > right) {
            return;
        }
        while (left < right) {
            char tem = s[left];
            s[left] = s[right];
            s[right] = tem;
            left++;
            right--;
        }
    }
}

2015年6月30日星期二

Text Justification leetcode

Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactlyL characters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.
For example,
words["This", "is", "an", "example", "of", "text", "justification."]
L16.
Return the formatted lines as:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]

下面讲解引用自http://codeganker.blogspot.com/2014/04/text-justification-leetcode.html
这 道题属于纯粹的字符串操作,要把一串单词安排成多行限定长度的字符串。主要难点在于空格的安排,首先每个单词之间必须有空格隔开,而当当前行放不下更多的 单词并且字符又不能填满长度L时,我们要把空格均匀的填充在单词之间。如果剩余的空格量刚好是间隔倍数那么就均匀分配即可,否则还必须把多的一个空格放到 前面的间隔里面。实现中我们维护一个count计数记录当前长度,超过之后我们计算共同的空格量以及多出一个的空格量,然后将当行字符串构造出来。最后一 个细节就是最后一行不需要均匀分配空格,句尾留空就可以,所以要单独处理一下。时间上我们需要扫描单词一遍,然后在找到行尾的时候在扫描一遍当前行的单 词,不过总体每个单词不会被访问超过两遍,所以总体时间复杂度是O(n)。而空间复杂度则是结果的大小(跟单词数量和长度有关,不能准确定义,如果知道最 后行数r,则是O(r*L))。代码如下:” 
public class Solution {
    public List<String> fullJustify(String[] words, int maxWidth) {
        List<String> res = new ArrayList<String>();
        if (words == null || words.length == 0) {
            return res;
        }
        int count = 0;//记录当前字符长度
        int last = 0;// 记录这一行起始字符的位置
        for (int i = 0; i < words.length; i++) {
            if (count + words[i].length() + i - last > maxWidth) {//i - last 是表示这一行单词之间空格总数
                i--;
                int spacenum = 0;
                int extrnum = 0;
                if (i - last > 0) {
                    spacenum = (maxWidth - count) / (i - last);//每个字符之间平均要有几个空格
                    extrnum = (maxWidth - count) % (i - last);//多余出来的空格
                }
                StringBuilder tem = new StringBuilder();
                for (int j = last; j <= i; j++) {
                    tem.append(words[j]);
                    if (j < i) {//第i个字符(每行最后一个)后面没有空格
                        for (int k = 0; k < spacenum; k++) {
                            tem.append(" ");
                        }
                        if (extrnum > 0) {//添加多余的空格
                            tem.append(" ");
                        }
                        extrnum--;
                    }
                }
                for (int j = tem.length(); j < maxWidth; j++) {//这个for循环作用于一行只有一个单词还maxWidth没填满一行的情况
                    tem.append(" ");
                }
                res.add(tem.toString());
                count = 0;
                last = i + 1;//下一个开始位置
            } else {
                count += words[i].length();
            }
        }
        StringBuilder tem = new StringBuilder();
        for (int i = last; i < words.length; i++) {//处理最后一行
            tem.append(words[i]);
            if (tem.length() < maxWidth) {
                tem.append(" ");
            }
        }
        for (int j = tem.length(); j < maxWidth; j++) {
            tem.append(" ");
        }
        res.add(tem.toString());
        return res;
    }
}

Word Search leetcode

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.
这道题的原理就是利用深度优先搜索, 从一个点出发, 上下左右搜索看是否能找到相等于word的字符串. 因为每一次的dfs访问的点不能被二次访问, 所以要维护一个m * n 的boolean矩阵 记录访问过的点.
对于每一个点的dfs时间是O(m*n)。我们对每个顶点都要做一次搜索,所以总的时间复杂度最坏是O(m^2*n^2),空间上就是要用一个数组来记录访问情况,所以是O(m*n)

public class Solution {
    public boolean exist(char[][] board, String word) {
        if (word == null || word.length() == 0) {
            return true;
        }
        if (board == null || board.length == 0 || board[0].length == 0) {
            return false;
        }
        boolean[][] used = new boolean[board.length][board[0].length];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (helper(board, word, 0, i, j, used)) {
                    return true;
                }
            }
        }
        return false;
    }
    private boolean helper(char[][] board, String word, int index, int i, int j, boolean[][] used) {
        if (index == word.length()) {
            return true;
        }
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || used[i][j] || board[i][j] != word.charAt(index)) {
            return false;
        }
        used[i][j] = true;
        boolean res = helper(board, word, index + 1, i + 1, j, used) ||helper(board, word, index + 1, i - 1, j, used) || helper(board, word, index + 1, i, j + 1, used) || helper(board, word, index + 1, i, j - 1, used);
        used[i][j] = false;
        return res;
    }
}

2015年6月28日星期日

Regular Expression Matching leetcode

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
(注意 ' * ' 匹配零个或者多个前面的元素 不能单独出现, 第二个string只要有一部分匹配第一个就可以)
这道题有两个case
1. 第二个char不是'*':
判定的第一个元素是否match 然后再递归match后面元素
2. 第二个char是' * '
p元素的第一个元素是. 或者p能匹配第i个元素 然后递归的match s的i+1后面 和p的* 后面元素
specail case p的长度是0 或者1 
public class Solution {
    public boolean isMatch(String s, String p) {
        if (p.length() == 0) {
            return s.length() == 0;
        }
        if (p.length() == 1) {//长度为1是special case
            return (s.length() == 1) && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.');
        }
        if (p.charAt(1) != '*') {// case 1 第二个元素不是*
            if (s.length() == 0) {
                return false;
            } else {
                return (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.') && isMatch(s.substring(1), p.substring(1));
            }
        } else {// case 2 第二个元素是*
            if (isMatch (s, p.substring(2))) {//case2.1 *不代表任何element
                return true;
            }
            int i = 0;
            //case2.2 * 代表一个或者多个element
            while (i < s.length() && (s.charAt(i) == p.charAt(0) || p.charAt(0) == '.')) {
                //因为*可以匹配多个跟前边相同的元素 只要i跟前边相同就可以继续往下找
                if (isMatch(s.substring(i + 1), p.substring(2))) {
                    return true;
                }
                i++;
            }
            return false;
        }
    }
}

Wildcard Matching leetcode

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

如果s字符的i位和p字符的j位置如果想吻合则拿i+1 和j+1继续比较
用一个star来记录*出现的位置, 首先当前字符i先和*的下一位比较, 如果不符合的话, 那么用i+1和*下一位比较 以此类推
while循环以第一个字符的长度作为限定, 最后判定第一个字符循环完是否第二个字符也全部走完 走完true 否则false

public class Solution {
    public boolean isMatch(String s, String p) {
        int i = 0;
        int j = 0;
        int star = -1;
        int mark = -1;
        while (i < s.length()) {
            if (j < p.length() && (p.charAt(j) == s.charAt(i) || p.charAt(j) == '?')) {
                i++;
                j++;
            } else if (j < p.length() && p.charAt(j) == '*') {
                star = j;
                mark = i;
                j++;
            } else if (star != -1) {
                //匹配s中当前字符与p中*后面的字符,如果匹配,则在第一个if中处理,如果不匹配,则继续比较s中的下一个字符。
                j = star + 1;
                i = mark + 1;
                mark++;
            } else {
                return false;
            }
        }
        while (j < p.length() && p.charAt(j) == '*') {//如果字符串后面有多余的* 
            j++;
        }
        return j == p.length();
    }
}

Length of Last Word leetcode

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.
第一种方法是把string按照" " 分成string[] 返回最后一个
第二种方法是维护一个count 从后面往前数遇到第一个空格为止,返回count值 如果count为0 说明最后一个字符是空格 继续往前数一个string 
public class Solution {
    public int lengthOfLastWord(String s) {
        String[] tem = s.split(" ");
        if (tem.length == 0 || tem == null) {
            return 0;
        }
        return tem[tem.length - 1].length();
    }
}
public class Solution {
    public int lengthOfLastWord(String s) {
        if (s.length() == 0 || s == null) {
            return 0;
        }
        int count = 0;
        for (int i = s.length() - 1; i >= 0; i--) {
            if (s.charAt(i) != ' ') {
                count++;
            }
            if (s.charAt(i) == ' ' && count != 0) {
                return count;
            }
        }
        return count;
    }
}

Group Anagrams leetcode

Given an array of strings, return all groups of strings that are anagrams.
Note: All inputs will be in lower-case.
把给的string都变成charArray然后排序, 把sort好的再变成string 存入hashmap, map 的value值为一个list<> list内存放变形之前的string.
如果一个string在hashmap中出现过 这个string一定是个变形词 把各个string放入对应的list中,遍历一次时间复杂度O(nlogn) + O(n*klogk) = O(nlogn)

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> res = new ArrayList<List<String>>();
        if (strs == null || strs.length == 0) {
            return res;
        }
        Arrays.sort(strs);
        HashMap<String, List<String>> map = new HashMap<String, List<String>>();
        for (String s : strs) {
            char[] chararray = s.toCharArray();
            Arrays.sort(chararray);
            String temstr = new String(chararray);
            if (map.containsKey(temstr)) {
                map.get(temstr).add(s);
            } else {
                List<String> tem = new ArrayList<String>();
                tem.add(s);
                map.put(temstr, tem);
            }
        }
        for (List<String> l : map.values()) {
            res.add(l);
        }
        return res;
    }
}

Implement strStr() leetcode

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
就是给一个target 看target里面是否包含另外给定的字符
假设target长度m 匹配长度n, 对target每个长度为n的substring都检查一次 时间O((m- n)* n)= O(m*n)

public class Solution {
    public int strStr(String haystack, String needle) {
        if (haystack == null || needle == null || needle.length() == 0) {
            return 0;
        }
        if (needle.length() > haystack.length()) {
            return -1;
        }
        for (int i = 0; i <= haystack.length() - needle.length(); i++) {
            boolean res = true;
            for (int j = 0; j < needle.length(); j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    res = false;
                    break;
                }
            }
            if (res == true) {
                return i;
            }
        }
        return -1;
    }
}

2015年6月24日星期三

Simplify Path leetcode

Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
Corner Cases:
  • Did you consider the case where path = "/../"?
    In this case, you should return "/".
  • Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
    In this case, you should ignore redundant slashes and return "/home/foo".
"当遇到“/../"则需要返回上级目录,需检查上级目录是否为空。
当遇到"/./"则表示是本级目录,无需做任何特殊操作。 
当遇到"//"则表示是本级目录,无需做任何操作。
当遇到其他字符则表示是文件夹名,无需简化。
当字符串是空或者遇到”/../”,则需要返回一个"/"。
当遇见"/a//b",则需要简化为"/a/b"。"
所以把字符按照"/" 分出来 如果是"." 或者空(// 分出来是空)不做任何操作
如果是".." 就把arraylist中前一个数删除
如果是其他的就写入arraylist
当最后所有都写入arraylist完之后把arraylist中的string放入一个string中并以"/"相隔
如果最后的string长度为0,  就返回"/"
public class Solution {
    public String simplifyPath(String path) {
        if (path == null || path.length() == 0) {
            return path;
        }
        String[] list = path.split("/");
        ArrayList<String> tem = new ArrayList<String>();
        for (int i = 0; i < list.length; i++) {
            if (list[i].equals(".") || list[i].length() == 0) {
                continue;
            } else if (list[i].equals("..")) {
                if (tem.size() > 0) {
                    tem.remove(tem.size() - 1);
                }
            } else {
                tem.add(list[i]);
            }
        }
        StringBuilder res = new StringBuilder();
        for (String s : tem) {
            res.append("/" + s);
        }
        if (res.length() == 0) {
            return "/";
        } else {
            return res.toString();
        }
    }
}
public class Solution {
    public String simplifyPath(String path) {
        if (path == null || path.length() == 0) {
            return "";
        }
        Stack<String> stack = new Stack<String>();
        String[] list = path.split("/");
        for (String s : list) {
            if (s.equals( ".") || s.length() == 0) {
                continue;
            } else if (s.equals("..")) {
                if (! stack.isEmpty()) {
                    stack.pop();
                }
            } else {
                stack.push(s);
            }
        }
        StringBuilder res = new StringBuilder();
        while (!stack.isEmpty()) {
            String tem = stack.pop();
            res.insert(0, "/" + tem );
        }
        if (res.length() == 0) {
            return "/";
        } else {
        
            return res.toString();
        }
    }
}

2015年5月31日星期日

Count and Say leetcode

The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 111221, ...
1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.
Given an integer n, generate the nth sequence.
Note: The sequence of integers will be represented as a string.
 n = 1,输出一个1。
 n = 2,看n=1那一行,1个1,输出11。
 n = 3,看n=2那一行,2个1,输出:21。
 n = 4,看n=3那一行,一个2一个1,输出:1211。
以此类推。(注意这里n是从1开始的)
int i--> string : str + ""+i
char c -- > string str + "" + c

public class Solution {
    /**
     * @param n the nth
     * @return the nth sequence
     */
    public String countAndSay(int n) {
        if (n < 0) {
            return "";
        }
        String cur = "1";
        int count = 1;
        for (int j = 1; j < n; j++) {//因为第0位是1 所以从第一位开始
            StringBuilder res = new StringBuilder();
            for (int i = 0; i < cur.length(); i++ ) {
                if (i < cur.length() - 1 && cur.charAt(i) == cur.charAt(i + 1)) {
                    count++;
                } else {
                    res.append(count + "" + cur.charAt(i));
                    count = 1;
                }
                
            }
            cur =  res.toString();
        }
        return cur;
    }
}


Valid Parentheses leetcode

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.
用stack实现, 左括号都push到stack中 注意返回时候是要确保stack为空才能true

时间O(n)
 
public class Solution {
    public boolean isValid(String s) {
        if (s == null || s.length() == 0) {
            return false;
        }
        Stack<Character> stack = new Stack<Character>();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '(' ||s.charAt(i) == '[' || s.charAt(i) == '{') {
                stack.push(s.charAt(i));
            } else if (s.charAt(i) == ')' || s.charAt(i) == ']' || s.charAt(i) == '}') {
                if (stack.size() == 0) {
                    return false;
                }
                char c = stack.pop();
                if (s.charAt(i) == ')') {
                    if (c != '(') {
                        return false;
                    }
                } else if (s.charAt(i) == ']') {
                    if (c != '[') {
                        return false;
                    }
                } else {
                    if (c != '{') {
                        return false;
                    }
                }
            }
        }
        return stack.size() == 0; //防止有stack没清空
    }
}
//
public class Solution {
    public boolean isValid(String s) {
        HashMap<Character, Character> map = new HashMap<Character, Character>();
        map.put('(', ')');
        map.put('{', '}');
        map.put('[', ']');
        Stack<Character> stack = new Stack<Character>();
        for (int i = 0; i < s.length(); i++) {
            if (map.containsKey(s.charAt(i))) {
                stack.push(s.charAt(i));
            } else {
                if (stack.isEmpty() || map.get(stack.pop()) != s.charAt(i)) {
                    return false;
                }
            }
        }
        return stack.isEmpty();
    }
}

2015年5月28日星期四

Longest Common Prefix leetcode

Write a function to find the longest common prefix string amongst an array of strings.
暴力解法, 先找到所有字符里面最小长度(最长的前缀肯定小于等于这个长度).之后循环, 每个以第零个为参照逐位扫描, 如果不相同则返回当前记录的前缀
public class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs.length == 0 || strs == null) {
            return "";
        }
        int min = Integer.MAX_VALUE;
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < strs.length; i++) {
            min = Math.min(min, strs[i].length());
        }
        for (int i = 0; i < min; i++) {
            for (int j = 0; j < strs.length; j++) {
                if (strs[j].charAt(i) != strs[0].charAt(i)) {
                    return res.toString();
                }
            }
            res.append(strs[0].charAt(i));
        }
        return res.toString();
    }
}

Roman to Integer leetcode

Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
从后往前扫罗马字符, 由于罗马字符的形成标准 如果之前的字符小于之后的 则对于之前字符用减法 大于等于则加法.
所以把罗马字符和对应数字放入一个hashmap里 方便查找
public class Solution {
    public int romanToInt(String s) {
        if (s.length() == 0 || s == null) {
            return 0;
        }
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();
        map.put('M', 1000);
        map.put('D', 500);
        map.put('C', 100);
        map.put('L', 50);
        map.put('X', 10);
        map.put('V', 5);
        map.put('I', 1);
        int res = map.get(s.charAt(s.length() - 1));
        for (int i = s.length()-2; i >= 0; i--) {
            if (map.get(s.charAt(i + 1)) > map.get(s.charAt(i))) {
                res -= map.get(s.charAt(i));
            } else {
                res += map.get(s.charAt(i));
            }
        }
        return res;
    }
}

Integer to Roman leetcode

Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
羅馬數字共有7個,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。按照下述的規則可以表示任意正整數。需要注意的是罗马数字中没有“0”,與進位制無關。一般認為羅馬數字只用來記數,而不作演算。
  • 重複數次:一個羅馬數字重複幾次,就表示這個數的幾倍。
  • 右加左減:
    • 在較大的羅馬數字的右邊記上較小的羅馬數字,表示大數字加小數字。
    • 在較大的羅馬數字的左邊記上較小的羅馬數字,表示大數字减小數字。
    • 左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV
    • 但是,左減時不可跨越一個位數。比如,99不可以用IC(100 - 1)表示,而是用XCIX([100 - 10] + [10 - 1])表示。(等同於阿拉伯數字每位數字分別表示。)
    • 左減數字必須為一位,比如8寫成VIII,而非IIX。
    • 右加數字不可連續超過三位,比如14寫成XIV,而非XIIII。(見下方“數碼限制”一項。)
  • 加線乘千:
    • 在羅馬數字的上方加上一條橫線或者加上下標的Ⅿ,表示將這個數乘以1000,即是原數的1000倍。
    • 同理,如果上方有兩條橫線,即是原數的1000000(1000^{2})倍。
  • 數碼限制:
    • 同一數碼最多只能出現三次,如40不可表示為XXXX,而要表示為XL。
    • 例外:由於IV是古羅馬神話主神朱庇特(即IVPITER,古羅馬字母裡沒有J和U)的首字,因此有時用IIII代替IV。
每次寻找小于所给数字的最大值相减, 直到num的值为0


public class Solution {
    public String intToRoman(int num) {
        if (num < 0) {
            return "";
        }
        int[] intset = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        String[] strset = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        StringBuilder res = new StringBuilder();
        for (int i = 0; num != 0; i++) {
            while (num >= intset[i]) {
                num -= intset[i];
                res.append(strset[i]);
            }
        }
        return res.toString();
    }
}