LeetCode 之 string字符串二

来源:互联网 发布:ubuntu 查看重启日志 编辑:程序博客网 时间:2024/06/05 17:35

1. Strring 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.

spoilers alert... click to show requirements for atoi.

Requirements for atoi:

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.

As there is no need to consider float number, what we need concern here is
(1) "+" and "-"
(2) The boundary INT_MAX and INT_MIN
(3) Eliminate the spaces before.
(4) Meet non-digit after digit then return. 

Java

public int atoi(String str) {        int result =0;int sign = 1;int startIndex = 0;int len = str.length();int max = 2147483647;if(str.length()<=0) return 0;while(str.charAt(startIndex)==' '&&startIndex<len) startIndex++;if(str.charAt(startIndex)=='+') startIndex++;if(str.charAt(startIndex)=='-') {sign = -1;startIndex++;}for(;startIndex<len;startIndex++){if(str.charAt(startIndex)<'0'||str.charAt(startIndex)>'9') break;if(max/10<result||(max/10==result && max%10<(str.charAt(startIndex)-'0'))){return sign==1 ? Integer.MAX_VALUE:Integer.MIN_VALUE;}result = result*10+(int)(str.charAt(startIndex)-'0');//System.out.println(str.charAt(startIndex)-'0');}return result*sign;    }

leetcode 又更新了 test cases, 比如“+-21”这种情况。
Refactor: 09/23/2014
public int atoi(String str) {        if(str.length()<=0) return 0;int result = 0;int sign = 0;int startIndex = 0;while(startIndex<str.length() && str.charAt(startIndex)==' ') startIndex++;if(startIndex==str.length()) return 0;if(str.charAt(startIndex)=='+') {sign=1;startIndex++;}if(str.charAt(startIndex)=='-'){if(sign==1) return 0;sign = -1;startIndex++;}for(;startIndex<str.length();startIndex++){if(str.charAt(startIndex)<'0' || str.charAt(startIndex)>'9') break;else if((Integer.MAX_VALUE/10<result)||(Integer.MAX_VALUE/10==result && Integer.MAX_VALUE%10<str.charAt(startIndex)-'0')){return (sign==1 || sign==0) ? Integer.MAX_VALUE: Integer.MIN_VALUE;}else {result = result*10 + str.charAt(startIndex)-'0';}}return sign==-1 ? result*sign: result;    }


C++

int atoi(const char *str) {        int num=0;    int sign = 1;    int len = strlen(str);    int i=0;    while(str[i]==' ' && i<len) i++;    if(str[i] == '+') i++;    if(str[i] == '-') {sign =-1; i++;}    for(;i<len;i++){        //if(str[i]==' ') break;        if(str[i]<'0' || str[i] > '9') break;        if(INT_MAX/10 < num || INT_MAX/10 == num && INT_MAX%10 < (str[i]-'0')){            return sign == -1 ? INT_MIN : INT_MAX;            break;        }        num = num*10 + str[i] - '0';    }    return num*sign;    }
2. Anagrams

Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

Analysis:

Anagrams is two strings are using the same characters. 
One way to compare two strings is use sort(). e.g. 
sort(str1.begin(), str1.end()); 
sort(str1.begin(), str1.end());
if (str1.compare(str2)==0) // when two strings are equal, the func returns 0

A more efficient way:
1. Scan the whole string vector, for each string, store to a hash map with the "ordered string" as the key. O(n).
2. Scan the whole hash map, output the values where for one key the number of value >=2. O(n)

Note:
1. We can use multimap<string, string> in c++, which allows the duplicate key values.
2. To store key-value into multimap, use ".insert(pair<key_type, value_type>(key,value))"
3. Use "pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;" and
".equal_range()" which returns a iterator pair(ret) that the "first" is the lower bound and "second" is the upper bound, to get all the key-values pairs for one key.
4. To check the number of values in one key, use the .count(key) method.

Java

public List<String> anagrams(String[] strs) {        List<String> result = new ArrayList<>();        HashMap<String, Integer> anagramMap = new HashMap<String,Integer>();        for(int i=0;i<strs.length;i++){        String t1 = strs[i];        char [] s1= t1.toCharArray();        Arrays.sort(s1);        t1 = new String(s1);        if(!anagramMap.containsKey(t1)){        anagramMap.put(t1, i);        }else {result.add(strs[i]);if(anagramMap.get(t1)!=-1){result.add(strs[anagramMap.get(t1)]);anagramMap.put(t1, -1);}}        }        return result;    }
c++

vector<string> anagrams(vector<string> &strs) {        vector<string> result;    map<string,int> temp;    for(int i=0; i<strs.size();i++){        string str = strs[i];        sort(str.begin(),str.end());        if(temp.find(str) == temp.end()){            temp[str] = 1;        }        else{            temp[str]++;        }    }    for(int i=0; i<strs.size();i++){        string str = strs[i];        sort(str.begin(),str.end());        if(temp.find(str) != temp.end() && temp[str]>1){            result.push_back(strs[i]);        }    }    return result;    }

3. Text Justification

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."]
L: 16.

Return the formatted lines as:

[   "This    is    an",   "example  of text",   "justification.  "]

Note: Each word is guaranteed not to exceed L in length.

click to show corner cases.

Corner Cases:

  • A line other than the last line might contain only one word. What should you do in this case?

  • In this case, that line should be left-justified.

Analysis:

Not complicated in algorithm. It focused on implement.

1. count line word number & index

2. calculate interval space (average and extra space)

3. construct line string with word and space. there be difference between last line and other lines

4. record each line to result.

Java

public List<String> fullJustify(String[] words, int L) {        List<String> result = new ArrayList<>();int len = words.length;if(len<=0) return result;int i = 0;while(i<len){int start = i;//start indexint sum = 0;//level lengthwhile(i<len && sum+words[i].length()<=L){sum+=words[i].length()+1;i++;}int end = i-1;//end indexint intervalCount = end-start;//interval numberint avgSp = 0, leftSp = 0;if(intervalCount>0){avgSp = (L-sum+intervalCount+1)/intervalCount;leftSp = (L-sum+intervalCount+1)%intervalCount;}StringBuffer line = new StringBuffer();for(int j = start;j<end;j++){//construct line charline.append(words[j]);if(i==len)line.append(' ');else {int temp = avgSp;while(temp>0){line.append(' ');temp--;}if(leftSp>0){line.append(' ');leftSp--;}}}line.append(words[end]);while(line.length()<L){line.append(' ');}result.add(line.toString());}return result;    }

c++

vector<string> fullJustify(vector<string> &words, int L) {        vector<string> result;    if(0==words.size()) return result;    int i=0;    while(i<words.size()){        int start =i;        int sum=0;        while(i<words.size() && sum+words[i].size()<=L){            sum+=words[i].size()+1;            i++;        }        int end = i-1;        int intervalCount = end-start;//interval space between words, "abc 1 bcd 2 def"        int avgSp = 0, leftSp = 0;        if(intervalCount >0){            avgSp = (L-sum+intervalCount+1)/intervalCount;            leftSp = (L-sum+intervalCount+1)%intervalCount;        }        string line;// construct new line        for(int j=start; j<end;j++){            line += words[j];            if(i == words.size())// the last line                line.append(1,' ');            else{                line.append(avgSp,' ');//average space                if(leftSp>0){//extra space                    line.append(1,' ');                    leftSp--;                }            }        }        line+=words[end];// add last word        if(line.size()<L)            line.append(L-line.size(),' ');        result.push_back(line);    }    return result;       }

4. 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:

from end to start position, use a new array to store temproary digit.
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.

c++

string multiply(string num1, string num2) {       if(num1.size() ==0 || num2.size() == 0) return "0";        string res(num1.size()+num2.size(),'0');        std::reverse(num1.begin(),num1.end());        std::reverse(num2.begin(),num2.end());    for(int i=0;i<num1.size();i++){        int digit1 = num1[i]-'0';        int carry = 0;        for(int j=0;j<num2.size();j++){            int digit2 = num2[j]-'0';            int exist = res[i+j]-'0';            res[i+j] = (digit1*digit2+carry+exist)%10 + '0';            carry = (digit1*digit2+carry+exist)/10;        }        if(carry>0){            res[i+num2.size()] = carry +'0';        }    }    std::reverse(res.begin(),res.end());    int start = 0;    while(res[start]=='0' && start<res.size()){        start++;    }    if(start == res.size()) {return "0";}    return res.substr(start,res.size()-start);}


Java

public String multiply(String num1, String num2) {        int len1 = num1.length();int len2 = num2.length();        if(len1 == 0 || len2==0) return "0";        int result[] = new int[len1+len2];        for(int i=0;i<len1;i++){        int carry = 0;        int digit1 = num1.charAt(len1-1-i)-'0';        for(int j=0;j<len2;j++){        int digit2 = num2.charAt(len2-1-j)-'0';        result[i+j] += digit1*digit2+carry;        carry = result[i+j]/10;        result[i+j] %=10;        }        result[i+len2]+=carry;        }                int i = len1+len2-1;        while(i>0 && result[i]==0) i--;        StringBuilder temp = new StringBuilder("");        while(i>=0)        temp.append((char)(result[i--]+'0'));        return temp.toString();    }

5. 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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "a*") → trueisMatch("aa", ".*") → trueisMatch("ab", ".*") → trueisMatch("aab", "c*a*b") → true
Analysis:

待匹配串为S,匹配串为P。
简化问题,假设P中没有'*',那么我们只需要一位一位的比较S和P。

回到原问题,对于S[i]和P[j]:
如果P[j+1]!='*',S[i] == P[j]=>匹配下一位(i+1, j+1),S[i]!=P[j]=>匹配失败;
如果P[j+1]=='*',S[i]==P[j]=>匹配下一位(i+1, j+2)或者(i, j+2),S[i]!=P[j]=>匹配下一位(i,j+2)。
匹配成功的条件为S[i]=='\0' && P[j]=='\0'。

采用递归实现:

c++

bool isMatch(const char *s, const char *p) {        if(*p=='\0') return *s =='\0';    //next char is not '*':must match current character    if(*(p+1)!='*'){               return ((*p==*s)||(*p=='.'&& *s!='\0')) && isMatch(s+1,p+1);    }    //next char is '*'    while((*p==*s)||(*p=='.' && *s!='\0')){        if(isMatch(s,p+2)) return true;        s++;    }    return isMatch(s,p+2);    }

确定了递归以后,使用java来实现这个问题,会遇到很多和c不一样的地方,因为java对字符 的控制不像c语言指针那么灵活charAt一定要确定某个位置存在才可以使用.
如果pattern是"x*"类型的话,那么pattern每次要两个两个的减少.否则,就是一个一个 的减少. 无论怎样减少,都要保证pattern有那么多个.比如s.substring(n), 其中n 最大也就是s.length()

public boolean isMatch(String s, String p) {        if(p.length()==0) return s.length()==0;        if(p.length()==1)        return (s.length()==1)&&(p.charAt(0)==s.charAt(0)||p.charAt(0)=='.');        if(p.charAt(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 {while(s.length()>0 && (p.charAt(0)==s.charAt(0)||p.charAt(0)=='.')){if(isMatch(s, p.substring(2)))return true;s = s.substring(1);}return isMatch(s, p.substring(2));}    }

6. Wildcard 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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "a*") → trueisMatch("aa", ".*") → trueisMatch("ab", ".*") → trueisMatch("aab", "c*a*b") → true
Analysis:

待匹配串为S,匹配串为P。
简化问题,假设P中没有'*',那么我们只需要一位一位的比较S和P。

回到原问题,对于S[i]和P[j]:
如果P[j+1]!='*',S[i] == P[j]=>匹配下一位(i+1, j+1),S[i]!=P[j]=>匹配失败;
如果P[j+1]=='*',S[i]==P[j]=>匹配下一位(i+1, j+2)或者(i, j+2),S[i]!=P[j]=>匹配下一位(i,j+2)。
匹配成功的条件为S[i]=='\0' && P[j]=='\0'。

采用递归实现:

c++

bool isMatch(const char *s, const char *p) {        if(*p=='\0') return *s =='\0';    //next char is not '*':must match current character    if(*(p+1)!='*'){               return ((*p==*s)||(*p=='.'&& *s!='\0')) && isMatch(s+1,p+1);    }    //next char is '*'    while((*p==*s)||(*p=='.' && *s!='\0')){        if(isMatch(s,p+2)) return true;        s++;    }    return isMatch(s,p+2);    }

确定了递归以后,使用java来实现这个问题,会遇到很多和c不一样的地方,因为java对字符 的控制不像c语言指针那么灵活charAt一定要确定某个位置存在才可以使用.
如果pattern是"x*"类型的话,那么pattern每次要两个两个的减少.否则,就是一个一个 的减少. 无论怎样减少,都要保证pattern有那么多个.比如s.substring(n), 其中n 最大也就是s.length()

public boolean isMatch(String s, String p) {        if(p.length()==0) return s.length()==0;        if(p.length()==1)        return (s.length()==1)&&(p.charAt(0)==s.charAt(0)||p.charAt(0)=='.');        if(p.charAt(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 {while(s.length()>0 && (p.charAt(0)==s.charAt(0)||p.charAt(0)=='.')){if(isMatch(s, p.substring(2)))return true;s = s.substring(1);}return isMatch(s, p.substring(2));}    }



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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "*") → trueisMatch("aa", "a*") → trueisMatch("ab", "?*") → trueisMatch("aab", "c*a*b") → false
Analysis:

Greedy method

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'".

Java

public boolean isMatch(String s, String p) {        int slen = s.length();        int plen = p.length();        int i = 0, j=0;        int star = -1;        int sp = 0;        while(i<slen){        while(j<plen && p.charAt(j)=='*'){        star = j++;        sp = i;        }        if(j==plen || (s.charAt(i)!=p.charAt(j)&&p.charAt(j)!='?')){        if(star<0) return false;        else {j = star+1;i = sp++;}        }else {i++;j++;}        }        while(j<plen && p.charAt(j)=='*'){        j++;        }        return j == plen;    }

c++

bool isMatch(const char *s, const char *p) {        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;    }


7. ZigZag Conversion

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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "a*") → trueisMatch("aa", ".*") → trueisMatch("ab", ".*") → trueisMatch("aab", "c*a*b") → true
Analysis:

待匹配串为S,匹配串为P。
简化问题,假设P中没有'*',那么我们只需要一位一位的比较S和P。

回到原问题,对于S[i]和P[j]:
如果P[j+1]!='*',S[i] == P[j]=>匹配下一位(i+1, j+1),S[i]!=P[j]=>匹配失败;
如果P[j+1]=='*',S[i]==P[j]=>匹配下一位(i+1, j+2)或者(i, j+2),S[i]!=P[j]=>匹配下一位(i,j+2)。
匹配成功的条件为S[i]=='\0' && P[j]=='\0'。

采用递归实现:

c++

bool isMatch(const char *s, const char *p) {        if(*p=='\0') return *s =='\0';    //next char is not '*':must match current character    if(*(p+1)!='*'){               return ((*p==*s)||(*p=='.'&& *s!='\0')) && isMatch(s+1,p+1);    }    //next char is '*'    while((*p==*s)||(*p=='.' && *s!='\0')){        if(isMatch(s,p+2)) return true;        s++;    }    return isMatch(s,p+2);    }

确定了递归以后,使用java来实现这个问题,会遇到很多和c不一样的地方,因为java对字符 的控制不像c语言指针那么灵活charAt一定要确定某个位置存在才可以使用.
如果pattern是"x*"类型的话,那么pattern每次要两个两个的减少.否则,就是一个一个 的减少. 无论怎样减少,都要保证pattern有那么多个.比如s.substring(n), 其中n 最大也就是s.length()

public boolean isMatch(String s, String p) {        if(p.length()==0) return s.length()==0;        if(p.length()==1)        return (s.length()==1)&&(p.charAt(0)==s.charAt(0)||p.charAt(0)=='.');        if(p.charAt(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 {while(s.length()>0 && (p.charAt(0)==s.charAt(0)||p.charAt(0)=='.')){if(isMatch(s, p.substring(2)))return true;s = s.substring(1);}return isMatch(s, p.substring(2));}    }





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   NA P L S I I GY   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".


数学题。巨无聊的一道题,真正面试过程中,不大可能出这种问题。
n=4
P              I              N
A         L  S         I   G
Y   A       H    R
P              I

N=5
P               H
A          S  I
Y      I       R
P   L          I      G
A              N

所以,对于每一层主元素(红色元素)的坐标 (i,j)= (j+1 )*n +i
对于每两个主元素之间的插入元素(绿色元素),(j+1)*n -i


java

public String convert(String s, int nRows) {if(nRows <=1) return s;StringBuilder result = new StringBuilder();    if(s.length() ==0 ) return result.toString();    for(int i=0; i<nRows;i++){        for(int j=0,index=i; index<s.length();j++, index = (2*nRows-2)*j+i){            result.append(s.charAt(index));            if(i==0 || i==nRows-1){                continue;            }            if(index+(nRows-i-1)*2 < s.length())                result.append(s.charAt(index+(nRows-i-1)*2));        }    }    return result.toString();    }
c++

string convert(string s, int nRows) {        if(nRows <=1) return s;    string result;    if(s.size() ==0 ) return result;    for(int i=0; i<nRows;i++){        for(int j=0,index=i; index<s.size();j++, index = (2*nRows-2)*j+i){            result.append(1,s[index]);            if(i==0 || i==nRows-1){                continue;            }            if(index+(nRows-i-1)*2 < s.size())                result.append(1,s[index+(nRows-i-1)*2]);        }    }    return result;    }










 






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."]
L: 16.

Return the formatted lines as:

[   "This    is    an",   "example  of text",   "justification.  "]

Note: Each word is guaranteed not to exceed L in length.

click to show corner cases.

Corner Cases:

  • A line other than the last line might contain only one word. What should you do in this case?

  • In this case, that line should be left-justified.

Analysis:

Not complicated in algorithm. It focused on implement.

1. count line word number & index

2. calculate interval space (average and extra space)

3. construct line string with word and space. there be difference between last line and other lines

4. record each line to result.

Java

public List<String> fullJustify(String[] words, int L) {        List<String> result = new ArrayList<>();int len = words.length;if(len<=0) return result;int i = 0;while(i<len){int start = i;//start indexint sum = 0;//level lengthwhile(i<len && sum+words[i].length()<=L){sum+=words[i].length()+1;i++;}int end = i-1;//end indexint intervalCount = end-start;//interval numberint avgSp = 0, leftSp = 0;if(intervalCount>0){avgSp = (L-sum+intervalCount+1)/intervalCount;leftSp = (L-sum+intervalCount+1)%intervalCount;}StringBuffer line = new StringBuffer();for(int j = start;j<end;j++){//construct line charline.append(words[j]);if(i==len)line.append(' ');else {int temp = avgSp;while(temp>0){line.append(' ');temp--;}if(leftSp>0){line.append(' ');leftSp--;}}}line.append(words[end]);while(line.length()<L){line.append(' ');}result.add(line.toString());}return result;    }

c++

vector<string> fullJustify(vector<string> &words, int L) {        vector<string> result;    if(0==words.size()) return result;    int i=0;    while(i<words.size()){        int start =i;        int sum=0;        while(i<words.size() && sum+words[i].size()<=L){            sum+=words[i].size()+1;            i++;        }        int end = i-1;        int intervalCount = end-start;//interval space between words, "abc 1 bcd 2 def"        int avgSp = 0, leftSp = 0;        if(intervalCount >0){            avgSp = (L-sum+intervalCount+1)/intervalCount;            leftSp = (L-sum+intervalCount+1)%intervalCount;        }        string line;// construct new line        for(int j=start; j<end;j++){            line += words[j];            if(i == words.size())// the last line                line.append(1,' ');            else{                line.append(avgSp,' ');//average space                if(leftSp>0){//extra space                    line.append(1,' ');                    leftSp--;                }            }        }        line+=words[end];// add last word        if(line.size()<L)            line.append(L-line.size(),' ');        result.push_back(line);    }    return result;       }


 


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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "a*") → trueisMatch("aa", ".*") → trueisMatch("ab", ".*") → trueisMatch("aab", "c*a*b") → true
Analysis:

待匹配串为S,匹配串为P。
简化问题,假设P中没有'*',那么我们只需要一位一位的比较S和P。

回到原问题,对于S[i]和P[j]:
如果P[j+1]!='*',S[i] == P[j]=>匹配下一位(i+1, j+1),S[i]!=P[j]=>匹配失败;
如果P[j+1]=='*',S[i]==P[j]=>匹配下一位(i+1, j+2)或者(i, j+2),S[i]!=P[j]=>匹配下一位(i,j+2)。
匹配成功的条件为S[i]=='\0' && P[j]=='\0'。

采用递归实现:

c++

bool isMatch(const char *s, const char *p) {        if(*p=='\0') return *s =='\0';    //next char is not '*':must match current character    if(*(p+1)!='*'){               return ((*p==*s)||(*p=='.'&& *s!='\0')) && isMatch(s+1,p+1);    }    //next char is '*'    while((*p==*s)||(*p=='.' && *s!='\0')){        if(isMatch(s,p+2)) return true;        s++;    }    return isMatch(s,p+2);    }

确定了递归以后,使用java来实现这个问题,会遇到很多和c不一样的地方,因为java对字符 的控制不像c语言指针那么灵活charAt一定要确定某个位置存在才可以使用.
如果pattern是"x*"类型的话,那么pattern每次要两个两个的减少.否则,就是一个一个 的减少. 无论怎样减少,都要保证pattern有那么多个.比如s.substring(n), 其中n 最大也就是s.length()

public boolean isMatch(String s, String p) {        if(p.length()==0) return s.length()==0;        if(p.length()==1)        return (s.length()==1)&&(p.charAt(0)==s.charAt(0)||p.charAt(0)=='.');        if(p.charAt(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 {while(s.length()>0 && (p.charAt(0)==s.charAt(0)||p.charAt(0)=='.')){if(isMatch(s, p.substring(2)))return true;s = s.substring(1);}return isMatch(s, p.substring(2));}    }


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   NA P L S I I GY   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".


数学题。巨无聊的一道题,真正面试过程中,不大可能出这种问题。
n=4
P              I              N
A         L  S         I   G
Y   A       H    R
P              I

N=5
P               H
A          S  I
Y      I       R
P   L          I      G
A              N

所以,对于每一层主元素(红色元素)的坐标 (i,j)= (j+1 )*n +i
对于每两个主元素之间的插入元素(绿色元素),(j+1)*n -i


java

public String convert(String s, int nRows) {if(nRows <=1) return s;StringBuilder result = new StringBuilder();    if(s.length() ==0 ) return result.toString();    for(int i=0; i<nRows;i++){        for(int j=0,index=i; index<s.length();j++, index = (2*nRows-2)*j+i){            result.append(s.charAt(index));            if(i==0 || i==nRows-1){                continue;            }            if(index+(nRows-i-1)*2 < s.length())                result.append(s.charAt(index+(nRows-i-1)*2));        }    }    return result.toString();    }
c++

string convert(string s, int nRows) {        if(nRows <=1) return s;    string result;    if(s.size() ==0 ) return result;    for(int i=0; i<nRows;i++){        for(int j=0,index=i; index<s.size();j++, index = (2*nRows-2)*j+i){            result.append(1,s[index]);            if(i==0 || i==nRows-1){                continue;            }            if(index+(nRows-i-1)*2 < s.size())                result.append(1,s[index+(nRows-i-1)*2]);        }    }    return result;    }



0 0
原创粉丝点击