刷题链接
最长公共子串(不是子序列)
class Solution {
public:
/**
* longest common substring
* @param str1 string字符串 the string
* @param str2 string字符串 the string
* @return string字符串
*/
string LCS(string a, string b) {
// write code here
int n = a.size(), m = b.size();
vector<vector<int>> f(n + 1,vector<int>(m + 1));
/*
f[i][j] : 以a[i]和b[j]结尾的最长公共子串(不是子序列,子串连续)
*/
int maxlen = 0,idx = 0;
for(int i = 1;i <= n;i ++ )
for(int j = 1;j <= m ;j ++ )
{
if(a[i - 1] == b[j - 1])f[i][j] = f[i - 1][j - 1] + 1;
// else {
// a[i - 1] != b[j - 1] f[i][j] = 0; // 初始化以默认为0
// }
if(maxlen < f[i][j]){
maxlen = f[i][j];
idx = i; // idx记录从1开始,下面idx - maxlen + 1 -1
}
}
if(maxlen == 0) return "-1";
return a.substr(idx - maxlen,maxlen);
}
};
链表求和
用栈
来存储倒序,尾插法
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
ListNode* addInList(ListNode* head1, ListNode* head2) {
// write code here
stack<int> stk1,stk2;
while(head1){
stk1.push(head1->val);
head1=head1->next;
}
while(head2){
stk2.push(head2->val);
head2=head2->next;
}
int sum = 0, carry = 0;
ListNode *cur = NULL;
while(stk1.size() || stk2.size() || carry)
{
sum = 0;
if(stk1.size()){
sum += stk1.top();
stk1.pop();
}
if(stk2.size()){
sum += stk2.top();
stk2.pop();
}
sum += carry;
carry = sum / 10;
ListNode *t = new ListNode(sum % 10);
t->next = cur;
cur = t;
}
return cur;
}
};
二叉树的最近公共祖先
O ( n ) O(n) O(n)
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
// write code here
if(root == NULL) return -1;
if(root->val == o1 || root->val == o2) return root->val;
int left = lowestCommonAncestor(root->left, o1, o2);
int right = lowestCommonAncestor(root->right, o1, o2);
if(left == -1) return right;
if(right == -1) return left;
return root->val;
}
};
二叉树的之字形遍历
二叉树的遍历 + 奇数行反转
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector<vector<>>
*/
vector<vector<int> > res;
vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
// write code here
vector<vector<int> > res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
while(q.size()){
int n = q.size();
vector<int> cur;
while(n -- ){
auto t = q.front();
q.pop();
cur.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
res.push_back(cur);
}
for(int i = 0; i < res.size();i ++ )
if(i % 2) reverse(res[i].begin(),res[i].end());
return res;
}
};
大数加法
字符串模拟
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
string solve(string s, string t) {
// write code here
vector<int> a,b;
for(int i = s.size() - 1;i >= 0;i -- ) a.push_back(s[i] - '0');
for(int i = t.size() - 1;i >= 0;i -- ) b.push_back(t[i] - '0');
auto c = add(a,b);
string res;
for(int i = c.size() - 1;i >= 0;i -- ) res += c[i] + '0';
return res;
}
vector<int> add(vector<int> &a,vector<int> &b)
{
vector<int> res;
int t = 0;
for(int i = 0;i < a.size() || i < b.size();i ++ )
{
if(i < a.size()) t += a[i];
if(i < b.size()) t += b[i];
res.push_back(t % 10);
t /= 10;
}
if(t) res.push_back(t);
return res;
}
};
反转字符串
双指针原地交换
class Solution {
public:
/**
* 反转字符串
* @param str string字符串
* @return string字符串
*/
string solve(string str) {
// write code here
for(int i = 0,j = str.size() - 1;i < j;i ++ ,j -- )
swap(str[i],str[j]);
return str;
}
};
两个链表的第一个公共结点
走两边,a+b+c
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
auto p = pHead1, q = pHead2;
while(p != q)
{
if(p) p = p->next;
else p = pHead2;
if(q) q = q->next;
else q = pHead1;
}
return p;
}
};
螺旋矩阵
方向矢量模拟
class Solution {
public:
vector<int> spiralOrder(vector<vector<int> > &matrix) {
if(matrix.empty() || matrix[0].empty()) return {
}; // 特判!!!
int n = matrix.size(), m = matrix[0].size();
int dx[] = {
-1,0,1,0}, dy[] = {
0,1,0,-1}; // 四个方向矢量
vector<vector<bool>> st(n,vector<bool>(m));
vector<int> res;
int x = 0,y = 0,d = 1;
for(int i = 0;i < n * m;i ++)
{
res.push_back(matrix[x][y]);
st[x][y] = true;
int a = x + dx[d], b = y + dy[d];
if(a < 0 || a >= n || b < 0 || b >= m || st[a][b])
{
d = (d + 1) % 4;
a = x + dx[d], b = y + dy[d];
}
x = a, y = b;
}
return res;
}
};
重建二叉树
递归构建二叉树,根据前序遍历找到根,中序遍历根左边是左子树,右边是右子树,递归处理。
#include <unordered_map>
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
unordered_map<int,int> pos;
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
int n = vin.size();
for(int i = 0;i < n;i ++ ) pos[vin[i]] = i;
return dfs(pre, vin,0,n - 1,0,n - 1);
}
TreeNode* dfs(vector<int> &pre,vector<int> &inorder,int pl,int pr,int il,int ir)
{
if(pl > pr) return NULL;
int val = pre[pl];
int k = pos[val];
int len = k - il;
TreeNode *root = new TreeNode(val);
root->left = dfs(pre,inorder,pl + 1,pl + len,il,k - 1);
root->right = dfs(pre,inorder,pl + len + 1,pr,k + 1,ir);
return root;
}
};
求平方根
值域二分,边界处理
class Solution {
public:
/**
*
* @param x int整型
* @return int整型
*/
int sqrt(int x) {
// write code here
int l = 0,r = x;
while(l < r)
{
int mid = (long long)l + r + 1 >> 1; // 防止溢出
if(mid <= x / mid) l = mid; // 防止溢出
else r = mid - 1;
}
return r;
}
};