1,验证一个字符串是否是回文串。
需要一个指向头部的变量和指向尾部的变量,从字符串的两边来遍历,遇到除字母和数字以外的字符则跳过,如果遍历完整个字符串后前后字母都能匹配上,则是回稳返回true.注意:空串也是回文。
需要注意的几点:(1)、对大小写不敏感,需要把所有字母小写都转换成大写,或者大写都转换成小写,用toupper()函数。
(2)、遇到非字母、数字要跳过,用到isalnum()函数
bool IsPalindrom(string s)
{
int first = 0, last = s.size() - 1;
while (first <= last)
{
while (!isalnum(s[first]) && first < last)
{
first++;
}
while (!isalnum(s[last]) && first < last)
{
last--;
}
if (toupper(s[first]) != toupper(s[last]))
return false;
first++;
last--;
}
return true;
}
2,模拟实现strstr.(找子串)
int strStr(string haystack, string needle)
{
int m = haystack.size(), n = needle.size();
if (n == 0)
return 0;
for (int i = 0; i < m - n + 1;i++)
{
int j = 0;
while(haystack[i + j] == needle[j])
{
j++;
if (j == n)
return i;
}
j++;
}
return -1;
}
3,模拟实现atoi
int my_atoi(const char* str)
{
int num = 0;
int sign = 1;
const int n = strlen(str);
int i = 0;
while (str[i] == ' ' && i < n)
i++;
if (str[i] == '+')
i++;
else if (str[i] == '-')
{
sign = -1;
i++;
}
for (; i < n; i++)
{
if (str[i] < '0' || str[i] > '9')
break;
if (num > INT_MAX / 10 || (num == INT_MAX / 10 && (str[i] - '0') > INT_MAX % 10))
return sign == -1 ? INT_MIN : INT_MAX;
num = num * 10 + str[i] - '0';
}
return num * sign;
}
4,二进制数相加。
比如:a = “11” b = “1” return 100
二进制数想加,并且保存在string中,要注意的是如何将string和int之间互相转换,并且每位相加时,会有进位的可能,会影响之后相加的结果。而且两个输入string的长度也可能会不同。这时我们需要新建一个string,它的长度是两条输入string中的较大的那个,并且把较短的那个输入string通过在开头加字符‘0’来补的较大的那个长度。这时候我们逐个从两个string的末尾开始取出字符,然后转为数字,想加,如果大于等于2,则标记进位标志carry,并且给新string加入一个字符‘0’。
//二进制数相加
string addBinary(string a, string b)
{
string result;
const size_t n = a.size() > b.size() ? a.size() : b.size();
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
int carry = 0;
for (size_t i = 0; i < n; ++i)
{
const int ai = i < a.size() ? a[i] - '0' : 0;
const int bi = i < b.size() ? b[i] - '0' : 0;
const int val = (ai + bi + carry) % 2;
carry = (ai + bi + carry) / 2;
result.insert(result.begin(), val + '0');
}
if (carry == 1)
result.insert(result.begin(), '1');
return result;
}
5,找出最长回文子串
方法一:以字符串中的每一个字符为中心遍历字符串。
思路:本题的解决方法是从头到尾的遍历字符串S,以每个字符为中心,向两端不停的扩展,同时判断以当前字符为中心的两端字符是否相等,在判断的过程中找到最大的回文串长度,并记录下回文串开始的最左端,这样就找到了最大的回文串。但是这样做就遇到了一个问题:“abcab”这种个数为奇数的回文串可以计算出来,但是若是”abba”这样个数为偶数的情况,该如何计算?遇到这种情况,则,可以判断相邻两字符是否相等来判断是否为回文串,针对s=“abba”,我们发现 i=1时,s[i]==s[i+1],然后同时向两端扩,发现s[ 0]=s[ 2],这样该串也为回文串,所以,在判断以某字符为中心的时候,要分两种情况,即,回文串中字符的个数为奇数和为偶数的情况。时间复杂度是O(n*n)。
//最长回文串
string longestPalindrome(string s)
{
string res = "";
int len = s.size();
if (len == 1)
return s;
int maxlen = 0, curlen = 0, sbegin;
int left, right;
for (int i = 0; i < len; ++i)
{
if (len % 2 == 0)
{
left = i - 1;
right = i + 1;
}
else
{
left = i;
right = i + 1;
}
while (left >= 0 && right < len && s[left] == s[right])
{
curlen = right - left;
if (curlen > maxlen)
{
maxlen = curlen;
sbegin = left;
}
left--;
right++;
}
}
res = s.substr(sbegin, maxlen + 1); //substring()为前闭后开
return res;
}
还有一种O(N)的解法:
http://www.cnblogs.com/love-yh/p/7072161.html
6,求字符串中最后一个单词的长度。
比如:“Hello world” return 5
//求最后一个单词的长度 顺序扫描字符串,求出每个单词的长度
int lengthOflastWord(const char* s)
{
int len = 0;
while (*s)
{
if (*s != ' ')
++len;
else
len = 0;
}
return len;
}
7,Regular Expression Matching (正则表达式匹配)
实现支持“.”和“*”的正则表达式匹配。
“.” 匹配支持单个字符
“*” 匹配零个或多个前面的元素
匹配应该覆盖到整个输入的字符串(而不是局部的)
比如:
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
bool IsMatch(const char* s, const char* p)
{
if (*p == '\0')
return *s == '\0';
//next char is not '*',then must match current character
if (*(p + 1) != '*')
{
if (*p == *s || *p == '.' && *s != '\0')
{
return IsMatch(s + 1, p + 1);
}
else
return false;
}
else
{//next char is '*'
while (*p == *s || (*p == '.' && *s != '\0'))
{
if (IsMatch(s, p + 2))
return true;
s++;
}
return IsMatch(s, p + 2);
}
}
8, 给定一个String类型数组,要求写一个方法,返回数组中这些字符串的最长公共前缀。举个例子:假如数组为[“123”,”12”,”4”],经过这个方法返回的结果就应该是”“。因为”123”,”12”,”4”并没有共同的前缀,虽然”123”,”12”的公共最长前缀是”12”,但是这个公共前缀”12”与”4”没有公共前缀,所以最后返回的结果就是”“。
最简单的思路就是将str[0],当作临时最长公共前缀,然后用这个前缀依次和剩下的字符串进行前缀比较,都比较完后,就将最后得到的最新公共最长前缀返回即可。
//Longest Common Prefix
string longestCommonPrefix(vector<string> &str)
{
if (str.empty())
return "";
int right_most = str[0].size() - 1;
for (size_t i = 1; i < str.size(); ++i)
{
for (int j = 0; j <= right_most; j++)
{
if (str[i][j] != str[0][j])
right_most = j - 1;
}
}
return str[0].substr(0, right_most + 1);
}
9,给你一个字符串数组,返回所有的回文构词法的字符串。
Anagram(回文构词法)是指由颠倒字母顺序组成的单词,比如“dormitory”颠倒字母顺序会变成“dirty room”,“tea”会变成“eat”。回文构词法有一个特点:单词里的字母的种类和数目没有改变,只是改变了字母的排列顺序。
Input: [“tea”,”and”,”ate”,”eat”,”den”]
Output: [“tea”,”ate”,”eat”]
vector<string> anagrams(vector<string>& strs)
{
unordered_map<string, vector<string>> group;
for (const auto &s : strs)
{
string key = s;
sort(key.begin(), key.end());
group[key].push_back(s);
}
vector<string> result;
for (auto it = group.cbegin(); it != group.cend(); ++it)
{
if (it->second.size() > 1)
result.insert(result.end(), it->second.begin(), it->second.end());
}
return result;
}
10,简化UNIX下的路径。
题目的要求是输出Unix下的最简路径,Unix文件的根目录为”/”,”.”表示当前目录,”..”表示上级目录。
例如:
输入1:
/../a/b/c/./..
输出1:
/a/b
模拟整个过程:
“/” 根目录
“..” 跳转上级目录,上级目录为空,所以依旧处于 “/”
“a” 进入子目录a,目前处于 “/a”
“b” 进入子目录b,目前处于 “/a/b”
“c” 进入子目录c,目前处于 “/a/b/c”
“.” 当前目录,不操作,仍处于 “/a/b/c”
“..” 返回上级目录,最终为 “/a/b”
使用一个栈来解决问题。遇到’..’弹栈,遇到’.’不操作,其他情况下压栈。
string simplifyPath(string path)
5 {
6 stack<string> ss; // 记录路径名
7 for(int i = 0; i < path.size(); )
8 {
9 // 跳过斜线'/'
10 while(i < path.size() && '/' == path[i])
11 ++ i;
12 // 记录路径名
13 string s = "";
14 while(i < path.size() && path[i] != '/')
15 s += path[i ++];
16 // 如果是".."则需要弹栈,否则入栈
17 if(".." == s && !ss.empty())
18 ss.pop();
19 else if(s != "" && s != "." && s != "..")
20 ss.push(s);
21 }
22 // 如果栈为空,说明为根目录,只有斜线'/'
23 if(ss.empty())
24 return "/";
25 // 逐个连接栈里的路径名
26 string s = "";
27 while(!ss.empty())
28 {
29 s = "/" + ss.top() + s;
30 ss.pop();
31 }
32 return s;
33 }
11,Count and Say
本题是将数字从1开始,将当前数字转化为口语对应的数字。比如1口语是1个1,记作11;11读作2个1,记作21;21读作1个2,1个1,记作1211……
这道题算就是字符串处理的问题,序列中第一个字符串是“1”,接下来依次统计前一个字符串中连续相同字符的数量,并添加到下一字符串中。前15字符串如下(LeetCode上貌似只有18测试用例):
1
11
21
1211
111221
312211
13112221
1113213211
31131211131221
13211311123113112211
11131221133112132113212221
3113112221232112111312211312113211
1321132132111213122112311311222113111221131221
11131221131211131231121113112221121321132132211331222113112211
311311222113111231131112132112311321322112111312211312111322212311322113212221
string countAndSay(int n)
{
string s = "1";
for (int i = 1; i < n; ++i)
{
int count = 1;
string temp = "";
for (int j = 1; j < s.size(); ++j)
{
if (s[j] == s[j - 1])
{
++count;
}
else
{
temp = temp + (char)(count + '0') + s[j - 1];
count = 1;
}
}
s = temp + (char)(count + '0') + s[s.size() - 1];
}
return s;
}