刷题链接
反转链表
递推实现
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode *pre = NULL, *cur = pHead;
while(cur)
{
ListNode *next = cur->next;
cur->next = pre;
pre = cur, cur = next;
}
return pre;
}
};
递归
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(!pHead || !pHead->next) return pHead;
ListNode *tail = ReverseList(pHead->next);
pHead->next->next = pHead;
pHead->next = NULL;
return tail;
}
};
排序
快速排序
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型vector 待排序的数组
* @return int整型vector
*/
vector<int> MySort(vector<int>& arr) {
// write code here
int n = arr.size();
quick_sort(arr,0,n - 1);
return arr;
}
void quick_sort(vector<int> &q,int l,int r)
{
if(l >= r) return;
int x = q[l + r >> 1],i = l - 1,j = r + 1;
while(i < j)
{
do i ++; while(q[i] < x);
do j --; while(q[j] > x);
if(i < j) swap(q[i],q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
};
归并排序
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型vector 待排序的数组
* @return int整型vector
*/
vector<int> temp;
vector<int> MySort(vector<int>& arr) {
// write code here
int n = arr.size();
temp = vector<int>(n);
merge_sort(arr,0,n - 1);
return arr;
}
void merge_sort(vector<int> &q,int l,int r)
{
if(l >= r) return;
int mid = l + r >> 1;
merge_sort(q,l,mid),merge_sort(q,mid + 1,r);
int i = l,j = mid + 1,k = 0;
while(i <= mid && j<= r)
{
if(q[i] <= q[j]) temp[k ++ ] = q[i ++ ];
else temp[k ++ ] = q[j ++ ];
}
while(i <= mid) temp[k ++ ] = q[i ++];
while(j <= r) temp[k ++ ] = q[j ++ ];
for(int i =l,j = 0;i <= r;i ++ ,j ++ ) q[i] = temp[j];
}
};
设计LRU缓存结构
一个双链表 + 一个哈希表
#include <unordered_map>
class Solution {
public:
/**
* lru design
* @param operators int整型vector<vector<>> the ops
* @param k int整型 the k
* @return int整型vector
*/
struct Node{
int key,val;
Node *left, *right;
Node():key(0),val(0),left(NULL),right(NULL){}
};
Node *head,*tail;
unordered_map<int,Node*> hash;
int tot;
void insert(Node *p) // 头插法,最不常用在尾
{
p->left = head,p->right = head->right;
head->right->left = p, head->right = p;
}
void remove(Node *p)
{
p->left->right = p->right, p->right->left = p->left;
}
vector<int> LRU(vector<vector<int> >& operators, int k) {
// write code here
tot = 0;
head = new Node(); tail = new Node(); // 初始化头尾节点
head->right = tail,tail->left = head;
vector<int> res;
for(auto c : operators)
{
int op = c[0];
if(op == 1)
{
int key = c[1], val = c[2];
if(hash[key])
{
Node *p = hash[key];
remove(p);
p->val = val;
insert(p);
}
else
{
if(tot == k)
{
Node *p = tail->left;
remove(p);
hash.erase(p->key);
tot --;
delete p;
}
Node *p = new Node();
p->val = val, p->key = key;
hash[key] = p;
tot ++;
insert(p);
}
}
else
{
int key = c[1];
if(hash[key])
{
Node *p =hash[key];
res.push_back(p->val);
remove(p);
insert(p);
}
else
{
res.push_back(-1);
}
}
}
return res;
}
};
判断链表中是否有环
空间复杂度O(1),快慢指针。如果没要求空间复杂度,那么哈希表记录是否出现过也可以
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if(!head || !head->next) return false;
auto fast = head->next, slow = head;
while(slow != fast)
{
if(fast == NULL || fast->next == NULL) return false;
slow = slow->next;
fast = fast->next->next;
}
return true;
}
};
二叉树的遍历
栈模拟递归遍历。
另外,二叉树的递归遍历可以考虑根右左的遍历顺序,再反转。
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类 the root of binary tree
* @return int整型vector<vector<>>
*/
vector<vector<int> > res;
vector<vector<int> > threeOrders(TreeNode* root) {
// write code here
preorder(root);
inorder(root);
postorder(root);
return res;
}
void preorder(TreeNode* root)
{
vector<int> ans;
stack<TreeNode*> stk;
while(root || !stk.empty())
{
while(root){
ans.push_back(root->val);
stk.push(root);
root = root->left;
}
if(!stk.empty())
{
root = stk.top();
stk.pop();
root = root->right;
}
}
res.push_back(ans);
}
void inorder(TreeNode* root)
{
vector<int> ans;
stack<TreeNode*> stk;
while(root || !stk.empty())
{
while(root){
stk.push(root);
root = root->left;
}
if(!stk.empty())
{
root = stk.top();
stk.pop();
ans.push_back(root->val);
root = root->right;
}
}
res.push_back(ans);
}
void postorder(TreeNode* root)
{
vector<int> ans;
stack<TreeNode*> stk;
TreeNode *cur = root, *pre = NULL;
while(cur || !stk.empty())
{
while(cur){
stk.push(cur);
cur = cur->left;
}
cur = stk.top();
if(cur->right == NULL || cur->right == pre)
{
ans.push_back(cur->val);
stk.pop();
pre = cur;
cur = NULL;
}else{
cur = cur->right;
}
}
res.push_back(ans);
}
};
二分查找
如果不存在,返回应该插入的位置
下标从1开始
class Solution {
public:
/**
* 二分查找
* @param n int整型 数组长度
* @param v int整型 查找值
* @param a int整型vector 有序数组
* @return int整型
*/
int upper_bound_(int n, int v, vector<int>& a) {
// write code here
int l = 0,r = n;
while(l < r)
{
int mid = l + r >> 1;
if(a[mid] >= v) r = mid;
else l = mid + 1;
}
return r + 1;
}
};
最小的K个数
堆排,时间复杂度 O ( n l o g k ) O(nlogk) O(nlogk)
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
priority_queue<int> q;
for(auto c : input)
{
q.push(c);
if(q.size() > k) q.pop();
}
vector<int> res;
if(k > q.size()) return res;
while(q.size())
{
res.push_back(q.top());
q.pop();
}
return res;
}
};
快速选择算法nth_element()
,时间复杂度
O
(
n
)
O(n)
O(n)
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if(k > input.size()) return {};
nth_element(input.begin(),input.begin() + k - 1,input.end());
vector<int> res;
for(int i = 0;i < k;i ++) res.push_back(input[i]);
return res;
}
};
快速排序模板实现快速选择算法nth_element()
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if(k > input.size()) return {};
//nth_element(input.begin(),input.begin() + k - 1,input.end());
quick_sort(input,0,input.size() - 1,k);
vector<int> res;
for(int i = 0;i < k;i ++) res.push_back(input[i]);
return res;
}
void quick_sort(vector<int> &q,int l,int r,int k)
{
if(l >= r) return;
int x = q[l + r >> 1], i = l - 1,j = r + 1;
while(i < j)
{
do i++;while(q[i] < x);
do j--;while(q[j] > x);
if(i < j) swap(q[i],q[j]);
}
int cnt = j - l + 1;
if(cnt >= k) quick_sort(q,l,j,k);
else quick_sort(q,j + 1,r,k - cnt);
}
};
二叉树的层序遍历
队列bfs
/**
* 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> > levelOrder(TreeNode* root) {
// write code here
if(!root) return{};
bfs(root);
return res;
}
void bfs(TreeNode* root)
{
queue<TreeNode*> q;
q.push(root);
while(q.size())
{
int n = q.size();
vector<int> ans;
while(n -- ){
auto t = q.front();
q.pop();
ans.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
res.push_back(ans);
}
}
};
寻找第K大
nth_element()
函数
class Solution {
public:
int findKth(vector<int> a, int n, int K) {
// write code here‘
nth_element(a.begin(),a.begin() + n - K ,a.end()); // 是第K大,不是第K小
return a[n - K];
}
};
手动实现
class Solution {
public:
int findKth(vector<int> a, int n, int K) {
// write code here‘
quick_sort(a,0,n - 1,n - K + 1); // 第K大相等于第n - K小
return a[n - K];
}
void quick_sort(vector<int> &q,int l,int r,int k)
{
if(l >= r) return ;
int x = q[l + r >> 1], i = l - 1,j = r + 1;
while(i < j)
{
do i ++ ;while(q[i] < x);
do j -- ;while(q[j] > x);
if(i < j) swap(q[i],q[j]);
}
int cnt = j - l + 1;
if(cnt >= k) quick_sort(q,l,j,k);
else quick_sort(q,j + 1,r,k - cnt);
}
};
跳台阶
递归
class Solution {
public:
int jumpFloor(int number) {
return dfs(number);
}
int dfs(int x)
{
if(x == 1 || x == 2) return x;
return dfs(x - 1) + dfs(x - 2);
}
};
递推
class Solution {
public:
int jumpFloor(int n) {
if(n == 1 || n == 2) return n;
vector<int> f(n + 1);
f[1] = 1, f[2] = 2;
for(int i =3;i <= n;i ++ )
f[i] = f[i - 1] + f[i - 2];
return f[n];
}
};
优化空间
class Solution {
public:
int jumpFloor(int n) {
if(n == 1 || n == 2) return n;
vector<int> f(n + 1);
//f[1] = 1, f[2] = 2;
int a = 1,b = 2, c;
for(int i =3;i <= n;i ++ ){
//f[i] = f[i - 1] + f[i - 2];
c = a + b;
a = b, b = c;
}
return c;
}
};