LeetCode 之 string字符串一

来源:互联网 发布:知乎考研最后20天 编辑:程序博客网 时间:2024/05/16 16:18

1. Length of last word

Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.

If the last word does not exist, return 0.

Note: A word is defined as a character sequence consists of non-space characters only.

For example, 
Given s = "Hello World",
return 5.

这是一道实现题,从后往前扫描,如何判断最后一个word,有以下几种情况

1.“word   ”

2. "       "

3. "word"

4."  word  "

int lengthOfLastWord(const char *s) {    int length = strlen(s);    int count = 0;    for(int i= length-1; i>=0;i--){        if(s[i] == ' '){            if(count == 0) continue;            else return count;        }        count++;    }    return count;}

Java解法:

利用split()函数,通过空格“ ”将原字符串分组

public int lengthOfLastWord(String s) {        String [] splitStrings = s.split(" ");        for(int i=splitStrings.length-1;i>=0;i--){        if(splitStrings[i].length()>0)        return splitStrings[i].length();        }        return 0;    }



2. Longest Common Prefix

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

字符串搜索,实现题。

定义一个compare string存放最后结果,遍历数组,每次找到相应的prefix存到compare中

string longestCommonPrefix(vector<string> &strs) {    if(strs.size() == 0) return NULL;    string compare = strs[0];    for(int i=1; i<strs.size();i++){        string prefix;        int k=0;        while(k<compare.size() && k<strs[i].size()){            if(compare[k] != strs[i][k]) break;            prefix.append(1,compare[k]);            k++;        }        compare.clear();        compare.append(prefix.c_str());    }    return compare;}

解法二

scan from the first character, if it is same to all other strings, then scan the second one until meet different or null

java实现

public String longestCommonPrefix(String[] strs) {        if(strs.length == 0) return "";        boolean flag = true;for(int i=0;i<strs[0].length();i++){for(int j=0;j<strs.length;j++){if(i>=strs[j].length() || strs[0].charAt(i)!=strs[j].charAt(i)){flag = false;break;}}if(!flag) return strs[0].substring(0,i);}return strs[0];    }



3.Count and Say

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次循环构造第n个字符串,构造过程通过数前面的字符。注意这里用i<=result.size() 省去判断到达字符串末尾

 
string countAndSay(int n) {    string result = "1";    int level = 1;    while(level < n){        stringstream seq;        char last = result[0];        int count =0;        for(int i=0; i<=result.size();i++){            if(result[i] == last){                count++;                continue;            }            else{                seq<<count<<last;                count = 1;                last = result[i];            }        }        result = seq.str();        level++;    }    return result;}

Java

public String countAndSay(int n) {        String result = "1";        if(n==1) return result;        int level = 1;        while(level<n){        char last = result.charAt(0);        int count =0;        StringBuffer seq = new StringBuffer();        for(int i=0;i<result.length();i++){        if(last == result.charAt(i)){        count++;        continue;        }else {seq.append(count);seq.append(last);last = result.charAt(i);count=1;}        }        seq.append(count);seq.append(last);        result = seq.toString();        level++;        }        return result;    }


4. 

Implement strStr().

Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.

时间复杂度线性的解法明显是KMP算法

1. 普通的解法。

2. KMP 算法---算法导论32章

char *strStr(char *haystack, char *needle) {    if(haystack == NULL || needle == NULL) return NULL;    int hlength = strlen(haystack);    int nlength = strlen(needle);    if(hlength<nlength) return NULL;    for(int i=0; i<hlength-nlength+1;i++){        char *p = &haystack[i];        int j=0;        for(;j<nlength;j++){            if(*p == needle[j])                p++;            else                break;        }        if(j == nlength)            return --p;    }    return NULL;}

方法2

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


方法3

参考

http://blog.csdn.net/lin_bei/article/details/1252686

算法导论32章


5. Valid Palindrome

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.

Analysis:

Use Two pointers, scan from end to start.

Java

public boolean isPalindrome(String s) {        s = s.trim();if(s.length()<=0) return true;int start = 0;int end = s.length()-1;while(start<end){while(start<end && !(Character.isLetter(s.charAt(start))||Character.isDigit(s.charAt(start)))) start++;while(start<end &&  !(Character.isLetter(s.charAt(end))||Character.isDigit(s.charAt(end)))) end--;if(s.charAt(start)==s.charAt(end) || s.charAt(start)-'a'==s.charAt(end)-'A'||s.charAt(start)-'A' == s.charAt(end)-'a' ){start++;end--;}else {break;}}if(start>=end)return true;else {return false;}    }

Another one:

public boolean isPalindrome(String s) {        if(s.isEmpty()) return true;        int len = s.length();        int start = 0;        int end = len-1;        while(start<=end){        if(!isAlp(s.charAt(start))){        start++;        continue;        }        if(!isAlp(s.charAt(end))){        end--;        continue;        }        if(s.charAt(start)==s.charAt(end) || Math.abs(s.charAt(start)-s.charAt(end))==32){        start++;end--;        }else        return false;                }        return true;    }public boolean isAlp(char c){if((c<='z'&&c>='a')||(c<='Z'&&c>='A')|| (c>='0'&&c<='9'))return true;elsereturn false;}


c++

bool isPalindrome(string s) {      if(s.empty()) return true;    int len = s.length();    int r = len-1;    int l = 0;    while(l<=r){        if((s[l] >= 'a' && s[l]<='z') || (s[l]>='A' && s[l]<='Z')||(s[l])>='0'&& s[l]<='9'){            if((s[r] >= 'a' && s[r]<='z') || (s[r]>='A' && s[r]<='Z')||(s[r]>='0' && s[r]<='9')){                if(s[l] == s[r] || s[l]-'a'==s[r]-'A' || s[l]-'A' == s[r]-'a'){                    l++;                    r--;                }                else                    return false;            }else{                r--;                continue;            }        }        else{            l++;            continue;        }    }    return true;    }




6. Reverse words in a string

Given an input string, reverse the string word by word.

For example,
Given s = "the sky is blue",
return "blue is sky the".

click to show clarification.

Clarification:

  • What constitutes a word?
    A sequence of non-space characters constitutes a word.
  • Could the input string contain leading or trailing spaces?
    Yes. However, your reversed string should not contain leading or trailing spaces.
  • How about multiple spaces between two words?
    Reduce them to a single space in the reversed string.

java实现
public String reverseWords(String s) {        String newString = s.trim();if(newString.length()<=0) return s.trim();String []splitsStrings = newString.split(" ");int len = splitsStrings.length;StringBuilder sBuilder = new StringBuilder("");for(int i=len-1;i>=0;i--){if(splitsStrings[i].length()>0){sBuilder.append(splitsStrings[i]);sBuilder.append(" ");}}String resultString = sBuilder.toString();return resultString.trim();    }
  • public String trim()
    Returns a copy of the string, with leading and trailing whitespace omitted.

    If this String object represents an empty character sequence, or the first and last characters of character sequence represented by thisString object both have codes greater than '\u0020' (the space character), then a reference to thisString object is returned.

    Otherwise, if there is no character with a code greater than '\u0020' in the string, then a newString object representing an empty string is created and returned.

    Otherwise, let k be the index of the first character in the string whose code is greater than'\u0020', and let m be the index of the last character in the string whose code is greater than'\u0020'. A new String object is created, representing the substring of this string that begins with the character at indexk and ends with the character at index m-that is, the result ofthis.substring(km+1).

    This method may be used to trim whitespace (as defined above) from the beginning and end of a string.

    Returns:
    A copy of this string with leading and trailing white space removed, or this string if it has no leading or trailing white space.
  • StringBuilder

    public StringBuilder(String str)
    Constructs a string builder initialized to the contents of the specified string. The initial capacity of the string builder is16 plus the length of the string argument.
    Parameters:
    str - the initial contents of the buffer.
    Throws:
    NullPointerException - ifstr is null

C++

Analysis:

The clarification is very important, during the interview, one should think of these points without hint, and then implement the algorithm.

By checking the clarifications, the programming is straightforward, here provides a simple version which uses buffer strings:
(1)Loop from start to the end of the string:
          (a) if current char is space and word string is empty, continue.
          (b) if current char is space but word string is NOT empty, which means we meet the end of word, then output the word, reset the word, continue.
          (c) if current char is non-space char, add this char to the word string, continue
(2)Handle the last word:
      (a) if the last word is empty, which means the input is empty, or the input has only spaces, or the last char/chars are spaces.  Then just remove the last space in the output string and return.
      (b) if the last word is not empty, add the last word to the front of the output string, then remove the last space in the output string and return.

void reverseWords(string &s) {    string word;//tmp string to store each word    string res;// result string    int i = 0;    for(int i=0;i<s.size();i++){        if(s[i]==' ' && word.empty()) continue;//multiple spaces        if(s[i]==' ' && !word.empty()){// word ends            res = word+" "+res;// add word to result string            word = "";// reset the word            continue;        }        if(s[i]!=' '){//non space characters            word.push_back(s[i]);            continue;        }    }    if(!word.empty())//last word        s = word+" "+res;    else        s = res;    s = s.substr(0,s.size()-1);}




7. 

Substring with Concatenation of All Words

You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.

For example, given:
S"barfoothefoobarman"
L["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

Analysis:

Try to think this problem straightforward:
Say in L there are m strings with length n. 
What string is required to match in S?     A length of m*n string start with each position in S.
What is a match?  In the m*n long string, every string in L appear only once.

So the algorithm is:
Scan every m*n long string start from each position in S, see if all the strings in L have been appeared only once using Map data structure. If so, store the starting position.

Yes, do not consider any DP or DFS solutions, just using the hash map and loop.

注意考虑L中可能含有重复字符串,需要用两个map

c++实现

vector<int> findSubstring(string S, vector<string> &L) {        map<string, int> expectCount;    map<string, int> realCount;    vector<int> result;    int row = L.size();    if(row == 0) return result;    int len = (int)L[0].size();    for(int i=0; i< L.size(); i++){        expectCount[L.at(i)]++;    }    for(int i=0; i<=(int)S.size()- row*len;i++){        realCount.clear();        int j=0;        for(; j<row; j++){            string str = S.substr(i+j*len,len);            if(expectCount.find(str) != expectCount.end()){                realCount[str]++;            }else{                break;            }            if(realCount[str]>expectCount[str])                break;        }        if(j == row)            result.push_back(i);    }    return result;    }


Java实现

public ArrayList<Integer> findSubstring(String S, String[] L) {        ArrayList<Integer> result = new ArrayList<Integer>();        int num = L.length;        int eachLen = L[0].length();        if(num == 0 || eachLen ==0) return result;        HashMap<String, Integer> hMap2 = new HashMap<String,Integer>();    for(int j=0;j<num;j++){        int val = 1;if(hMap2.containsKey(L[j])){        val = hMap2.get(L[j]);        val++;}    hMap2.put(L[j], val);    }        for(int i=0;i<=S.length()-num*eachLen;i++){        HashMap<String, Integer> hMap = new HashMap<String,Integer>();        for(int j=0;j<num;j++){        hMap.put(L[j], 0);        }        int k =0 ;        while(k<num){        String str = S.substring(i+k*eachLen, i+eachLen*(k+1));        if(hMap.containsKey(str)){        int val = hMap.get(str);        hMap.put(str, ++val);        if(hMap.get(str)>hMap2.get(str)) break;                }else{        break;        }        k++;        }        if(k == num) result.add(i);        }                return result;    }

8.Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example,
S = "ADOBECODEBANC"
T = "ABC"

Minimum window is "BANC".

Note:
If there is no such window in S that covers all characters in T, return the emtpy string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

Analysis:

Use two map to store the expected char occured numbers(from T), realtime char occured numbers(From S)

Since we should implement this with O(n), we scan string S from the start to the end, use appeared varablile to recored how many chars have occued compared with T

If the (char is in T && its occued numbers < T), store it and its occued numbers in expectedMap, appeared++

If(appeared == T.lenth() )// substring could cover all chars in T

while(starting char is not in T || starting char numbers > expected number in T)

starting index++

if(win_len> current window length)

set new window

return ....


C++实现如下

string minWindow(string S, string T) {        if(S.size() == 0) return "";    if(T.size() > S.size()) return "";    int appearCount[256];    int expectCount[256];    memset(appearCount,0,256*sizeof(appearCount[0]));    memset(expectCount,0,256*sizeof(appearCount[0]));    for(int i=0; i<T.size();i++){        expectCount[T[i]]++;    }    int minV = INT_MAX, min_start=0;    int wid_start =0;    int appeared = 0;    for(int wid_end = 0; wid_end<S.size(); wid_end++){        if(expectCount[S[wid_end]] >0)        {            appearCount[S[wid_end]]++;            if(appearCount[S[wid_end]] <= expectCount[S[wid_end]])                appeared++;        }        if(appeared == T.size()){            while((appearCount[S[wid_start]]>expectCount[S[wid_start]]) || expectCount[S[wid_start]]==0)            {                appearCount[S[wid_start]]--;                wid_start++;            }            if(minV > (wid_end-wid_start+1))            {                minV = wid_end-wid_start+1;                min_start = wid_start;            }        }    }    if(minV == INT_MAX) return"";    return S.substr(min_start,minV);    }


Java实现如下

public String minWindow(String S, String T) {        int win_start = 0;        int win_realS = 0;        int win_len = Integer.MAX_VALUE;        int appeared = 0;        HashMap<Character, Integer> expected = new HashMap<Character, Integer>();        HashMap<Character, Integer> realAppeared = new HashMap<Character, Integer>();        for(int i=0;i<T.length();i++){//store T char into map        int val = 1;        if(expected.containsKey(T.charAt(i))){        val = expected.get(T.charAt(i));        val++;        }        expected.put(T.charAt(i), val);        }        for(int i=0;i<S.length();i++){        if(expected.containsKey(S.charAt(i))){        int val = 0;        if(realAppeared.containsKey(S.charAt(i))){        val = realAppeared.get(S.charAt(i));        val++;        }else{        val = 1;        }        realAppeared.put(S.charAt(i), val);        if(val<=expected.get(S.charAt(i)))        appeared++;        }        if(appeared == T.length()){//have all the chars        while(!expected.containsKey(S.charAt(win_start))        || (expected.containsKey(S.charAt(win_start)) && realAppeared.get(S.charAt(win_start))>expected.get(S.charAt(win_start)))){        if(!expected.containsKey(S.charAt(win_start)))        win_start++;        else{        int val = realAppeared.get(S.charAt(win_start));        val--;        realAppeared.put(S.charAt(win_start), val);        win_start++;        }        }                if(win_len>i-win_start+1){        win_len = i-win_start+1;        win_realS = win_start;        }        }        }        return (win_len == Integer.MAX_VALUE) ? "" : S.substring(win_realS, win_realS+win_len);    }


9. Longest Substring Without Repeating Characters 

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

从左往右扫描,当遇到重复字母时,以上一个重复字母的index +1,作为新的搜索起始位置。比如


直到扫描到最后一个字母。
C++实现

int lengthOfLongestSubstring(string s) {        int maxL=0;        int len =0;        int counts[26];        memset(counts, -1, 26*sizeof(int));            for(int i=0; i<s.size(); i++,len++){            if(counts[s[i]-'a']>=0){            maxL = max(maxL, len);            len = 0;            i = counts[s[i]-'a']+1;            memset(counts,-1,26*sizeof(int));        }        counts[s[i]-'a'] = i;    }    return max(len, maxL);    }


Java实现

public int lengthOfLongestSubstring(String s) {        if(s.length() == 0) return 0;int start = 0;int end = 0;int maxLen = 0;HashMap<Character, Integer> charMap = new HashMap<Character,Integer>();while(end<s.length()){if(!charMap.containsKey(s.charAt(end))){charMap.put(s.charAt(end), end);int len = end-start+1;maxLen = Math.max(len, maxLen);}else{int val = charMap.get(s.charAt(end));for(int i=start;i<val+1;i++)charMap.remove(s.charAt(i));start = val+1;charMap.put(s.charAt(end), end);}end++;}return maxLen;    }
v2

10 Interleaving String

Given s1s2s3, find whether s3 is formed by the interleaving of s1 and s2.

For example,
Given:
s1 = "aabcc",
s2 = "dbbca",

When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.

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

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

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

c++

<span style="font-family:Arial, Tahoma, Helvetica, FreeSans, sans-serif;font-size:12px;color:#444444;">bool isInterleave(string s1, string s2, string s3) {         if(s1.size()+s2.size() != s3.size()) return false;    bool **dp = new bool *[s1.size()+1];    for(int i=0; i<s1.size()+1; i++){        dp[i] = new bool [s2.size()+1];    }    dp[0][0] = true;    for(int i=1; i<s1.size()+1; i++){        if(s1[i-1]==s3[i-1] && dp[i-1][0])            dp[i][0] = true;    }    for(int j=1; j<s2.size()+1; j++){        if(s2[j-1]==s3[j-1] && dp[0][j-1])            dp[0][j] = true;    }    for(int i=1; i<s1.size()+1; i++){        for(int j=1; j<s2.size()+1; j++){            if(s1[i-1]==s3[i+j-1] && dp[i-1][j])                dp[i][j] = true;            if(s2[j-1]==s3[i+j-1] && dp[i][j-1])                dp[i][j] = true;        }    }    return dp[s1.size()][s2.size()];    }</span>
java

<span style="font-family:Arial, Tahoma, Helvetica, FreeSans, sans-serif;font-size:12px;color:#444444;">public boolean isInterleave(String s1, String s2, String s3) {        int n1 = s1.length();        int n2 = s2.length();        if(n1+n2!=s3.length()) return false;        boolean [][]flag = new boolean [n1+1][n2+1];        for(int i=0;i<=n1;i++){        for(int j=0;j<=n2;j++){        flag[i][j] = false;        }        }        flag[0][0] = true;        for(int i=1;i<=n1;i++){        if(s1.charAt(i-1)==s3.charAt(i-1)&& flag[i-1][0]) flag[i][0] = true;        }        for(int j=1;j<=n2;j++){        if(s2.charAt(j-1)==s3.charAt(j-1)&& flag[0][j-1]) flag[0][j] =true;        }        for(int i=1;i<=n1;i++){        for(int j=1;j<=n2;j++){        if((flag[i-1][j] && s1.charAt(i-1)==s3.charAt(i-1+j))||        (flag[i][j-1]&& s2.charAt(j-1)==s3.charAt(i+j-1))){        flag[i][j] = true;        }        }        }        return flag[n1][n2];    }</span>




未完待续

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.

Analysis:

Use Two pointers, scan from end to start.

Java

public boolean isPalindrome(String s) {        s = s.trim();if(s.length()<=0) return true;int start = 0;int end = s.length()-1;while(start<end){while(start<end && !(Character.isLetter(s.charAt(start))||Character.isDigit(s.charAt(start)))) start++;while(start<end &&  !(Character.isLetter(s.charAt(end))||Character.isDigit(s.charAt(end)))) end--;if(s.charAt(start)==s.charAt(end) || s.charAt(start)-'a'==s.charAt(end)-'A'||s.charAt(start)-'A' == s.charAt(end)-'a' ){start++;end--;}else {break;}}if(start>=end)return true;else {return false;}    }

Another one:

public boolean isPalindrome(String s) {        if(s.isEmpty()) return true;        int len = s.length();        int start = 0;        int end = len-1;        while(start<=end){        if(!isAlp(s.charAt(start))){        start++;        continue;        }        if(!isAlp(s.charAt(end))){        end--;        continue;        }        if(s.charAt(start)==s.charAt(end) || Math.abs(s.charAt(start)-s.charAt(end))==32){        start++;end--;        }else        return false;                }        return true;    }public boolean isAlp(char c){if((c<='z'&&c>='a')||(c<='Z'&&c>='A')|| (c>='0'&&c<='9'))return true;elsereturn false;}


c++

bool isPalindrome(string s) {      if(s.empty()) return true;    int len = s.length();    int r = len-1;    int l = 0;    while(l<=r){        if((s[l] >= 'a' && s[l]<='z') || (s[l]>='A' && s[l]<='Z')||(s[l])>='0'&& s[l]<='9'){            if((s[r] >= 'a' && s[r]<='z') || (s[r]>='A' && s[r]<='Z')||(s[r]>='0' && s[r]<='9')){                if(s[l] == s[r] || s[l]-'a'==s[r]-'A' || s[l]-'A' == s[r]-'a'){                    l++;                    r--;                }                else                    return false;            }else{                r--;                continue;            }        }        else{            l++;            continue;        }    }    return true;    }





1 0
原创粉丝点击