做了不少,选部分写讲解。
1. Median of Two Sorted Arrays
来源:
https://leetcode.com/problems/median-of-two-sorted-arrays/description/
题意:
给出两个有序数串,要求O(m+n)复杂度找出两个书串合起来之后的中位数。
思路
1.首先确定在合并后的有序数串中,中位数的下标(index),尽管不用真的合并
2.比较两个数串的最前数字,将指向小的数的指针往后移,移了一次救赎数出了一个最小数。直到数到所需下标的数,记录。这里要注意,连个数串,可能一个为空,可能两个不等长,指针后移的时候要注意判断。
代码
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
// 找中位数在“合并”后数串的下下标
int n = nums1.size() + nums2.size();
int index1, index2;
double result = 0;
if(n%2 == 1) {index1 = index2 = (n/2);}
else {index2 = n/2 ; index1 = index2 - 1;}
// 开始数下标,直到找到所需
auto it1 = nums1.begin();
auto it2 = nums2.begin();
vector<int>::iterator cur;
for(int i = 0; i <= index2; i++) {
if(it1 == nums1.end() && it2 != nums2.end()) {cur = it2; it2++;}
if(it1 != nums1.end() && it2 == nums2.end()) {cur = it1; it1++;}
if(it1 != nums1.end() && it2 != nums2.end()) {
if(*it1 <= *it2) {
cur = it1;
it1++;
} else {
cur = it2;
it2++;
}
}
if(i == index1) {result += *cur;}
if(i == index2) {result += *cur;}
}
return result/2;
}
};
2.Longest Palindromic Substring
来源:
https://leetcode.com/problems/longest-palindromic-substring/description/
题意:
给出一个有序数串,要求找出最短回文子串。
思路
这里最优的方法是马拉车算法(Manacher’s Algorithm),复杂度为O(n)。我是参考以下博客打出来的,因为觉得这题特别巧妙,所以也写下来。
参考的博客:http://www.cnblogs.com/grandyang/p/4475985.html
如果看不懂的话,用纸笔人肉跑一次就知道了。
代码
class Solution {
public:
string longestPalindrome(string s) {
// preProcess
string t = "$#";
for(int i = 0; i < s.length(); i++) {
t.push_back(s[i]);
t.push_back('#');
}
vector<int> p(t.length(), 0);
int mx = 0, id = 0, resLen = 0, resCenter = 0;
//process t
for(int i = 1; i < t.length(); i++) {
p[i] = (mx>id+p[id])?min(p[2*id-i],mx-id):1;
while(t[i+p[i]] == t[i-p[i]]) {p[i]++;}
if(p[i] + i > mx) {
mx = p[i] + i;
id = i;
}
if(p[i] > resLen) {
resLen = p[i];
resCenter = i;
}
}
return s.substr((resCenter-resLen)/2, resLen - 1);
}
};
3.ZigZag Conversion
来源:
https://leetcode.com/problems/zigzag-conversion/description/
题意:
给出一个有序字符串,按Z形走位后,再按横向顺序输出。
思路
画个图,就知道变换后,每个字符的对应位置
可以如图分成n-1行,每一大块当作一列。而每一大块内的每一行的便宜都是跟行数列数有函数对应关系的,因此可以用两重循环来输出。
但是我的代码没有过,我自己打点输出后发现,评测系统有问题。
我再return result之前输出了看到result是”AEBDC”,然是return到了评测系统就变成了”AEBD”,然后判我错。我也没办法的。
代码
class Solution {
public:
string convert(string s, int numRows) {
string output;
cout << s << endl;
if(numRows == 1 || numRows >= s.length()) return s;
if(numRows == 2) {
for(int i = 0; i < s.length(); i++) {
if (i % 2 == 0) {output += s[i];}
}
for(int i = 0; i < s.length(); i++) {
if (i % 2 == 1) {output += s[i];}
}
return output;
}
// numRows >= 3
int numCols = ((s.length() - 1))%(2*numRows - 3)==0?(((s.length() - 1))/(2*numRows - 3)):((s.length() - 1))/(2*numRows - 3)+1;
for(int i = 0; i < numRows; i++) {
for(int j = 0; j < numCols; j++) {
output += s[i + j*2*(numRows-1)];
cout << i << " " << j << " " << s[i + j*2*(numRows-1)] << " " << output << endl;
if(!(i==0 || i == numRows - 1)){
int k = j*2*(numRows-1) + numRows;
if(k < s.length()) {output += s[k];}
}
}
}
cout << output << endl;
return output;
}
};
10. Regular Expression Matching
来源:https://leetcode.com/problems/regular-expression-matching/description/
题意
实现仅有’*’和’.’通配符的正则表达式
思路
很惭愧,想不出,参考了solution才做出来。
看过答案后想一想,还是容易的。如果s是给定的字符串,p是要匹配的模式。
class Solution {
public:
bool isMatch(string s, string p) {
if(p.empty()) return s.empty();
if(p[1] == '*') {
return (!s.empty() && (s[0] == p[0] || p[0] == '.')&& isMatch(s.substr(1),p)) || isMatch(s, p.substr(2));
} else {
return !s.empty() && (s[0] == p[0] || p[0] == '.')&& isMatch(s.substr(1),p.substr(1));
}
}
};