您的位置:首页 > 其它

【算法设计作业】Week1

2017-09-09 00:07 211 查看
做了不少,选部分写讲解。



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));
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法设计