剑指58
问题类型:字符串反转
class Solution {
public:
void reverselen(string &a, int from, int to) {
char ch;
while (from < to) {
ch = a[from];
a[from] = a[to];
a[to] = ch;
from++;
to--;
}
}
string reverseLeftWords(string s, int n) {
int len = s.size();
if (n > 0) {
reverselen(s, 0, len - 1);
reverselen(s, 0, len - n - 1);
reverselen(s, len - n, len - 1);
}
return s;
}
};
leetcode1143
最长公共子序列
问题类型: LCS 动态规划,通过区分最后一个字符是否相同,相同则是前一个加一,否则是两个字符串减少一个字符中较大的情况
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int size1 = text1.size();
int size2 = text2.size();
int ans = 0;
vector<vector<int>> LCS(size1 + 1, vector<int>(size2 + 1));
for (int i = 0; i <= size1; ++i) {
LCS[i][0] = 0;
}
for (int j = 0; j <= size2; ++j) {
LCS[0][j] = 0;
}
for (int i = 1; i <= size1; ++i) {
for (int j = 1; j <= size2; ++j) {
if (text1[i - 1] == text2[j - 1]) {
LCS[i][j] = LCS[i - 1][j - 1] + 1;
} else {
LCS[i][j] = max(LCS[i][j - 1], LCS[i - 1][j]);
}
if (LCS[i][j] > ans) {
ans = LCS[i][j];
}
}
}
return ans;
}
};
leetcode300
LIS 可以用LCS解决,也可以直接用动态规划解决
class Solution {
public:
int lengthOfLIS(vector<int> &nums) {
vector<int> ans(nums.size() + 1);
int len = nums.size();
for(int i = 0; i < len; ++i)
{
ans[i] = 1;
}
for(int i = 0; i < len; ++i)
{
int Max = 1;
for(int j = 0; j < i; ++j)
{
if(nums[i] > nums[j] &&Max < ans[j] + 1)
{
Max = ans[j] + 1;
}
}
ans[i] = Max;
}
int sh = 0;
for(int i = 0; i < len; ++i)
{
if(sh < ans[i])
sh = ans[i];
}
return sh;
}
};
leecode_OFFer_38
两种方法:
1.通过递归
2.通过进行大小变化
class Solution {
public:
vector<string> ans;
vector<int> vis;
void chain(string s, int a, int n, string &t) {
if (n == a) {
ans.push_back(t);
return ;
}
for (int i = 0; i < n; ++i) {
if (vis[i] || (i > 0 && vis[i - 1] == 0 && s[i] == s[i - 1]))
continue;
vis[i] = 1;
t.push_back(s[i]);
chain(s, a + 1, n, t);
t.pop_back();
vis[i] = 0;
}
}
vector<string> permutation(string s) {
int len = s.size();
vis.resize(len);
sort(s.begin(), s.end());
for (int i = 0; i < len; ++i) {
vis[i] = 0;
}
string ch;
chain(s, 0, len, ch);
return ans;
}
};
class Solution {
public:
bool gethigher(string &s, int n) {
int i = n - 2;
while (i >= 0 && s[i] >= s[i + 1]) {
i--;
}
if (i < 0)
return false;
int j = n - 1;
while (s[j] <= s[i])
j--;
swap(s[i], s[j]);
sort(s.begin() + i + 1, s.end());
cout << s << endl;
return true;
}
vector<string> permutation(string s) {
int len = s.size();
vector<string> ans;
sort(s.begin(), s.end());
ans.push_back(s);
while (gethigher(s, len)) {
ans.push_back(s);
}
return ans;
}
};
其中第二种难点是在于排序的理解:首先从最低位(字符串最高位)+ 1开始遍历寻找更低位高于它,并找到在低于此位范围内大于它的最低位,进行交换,直至字符串最大
2.注意:交换之后可能会跳过一些位置所以交换之后将之后的字符串再升序排序,确保增幅最小