第 1 天 栈与队列(简单)

剑指 Offer 09. 用两个栈实现队列

class CQueue {
public:
CQueue() { }
stack<int>s1,s2;
void appendTail(int value) {
s1.push(value);
} int deleteHead() {
if(s2.empty())
{
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
}
if(s2.empty())
return -1;
int tmp=s2.top();
s2.pop();
return tmp;
}
}; /**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/

剑指 Offer 30. 包含min函数的栈

构造一个辅助栈,使辅助栈顶元素始终为当前栈内元素的最小值

class MinStack {
public:
/** initialize your data structure here. */
MinStack() { }
stack<int>st;
stack<int>m;
void push(int x) {
st.push(x);
if(m.empty()||m.top()>=x)
m.push(x);
} void pop() {
if(st.top()==m.top())
m.pop();
st.pop();
} int top() {
return st.top();
} int min() {
return m.top();
}
}; /**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->min();
*/

第 2 天 链表(简单)

剑指 Offer 06. 从尾到头打印链表

存入数组中然后反转一下

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int>v;
while(head)
{
v.push_back(head->val);
head=head->next;
}
reverse(v.begin(),v.end());
return v;
}
};

剑指 Offer 24. 反转链表

让当前节点的下一个节点指向上一个节点,使用一个临时的指针来实现

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *cnt=head,*ans=NULL;
while(cnt)
{
ListNode *tmp=cnt->next;
cnt->next=ans;
ans=cnt;
cnt=tmp;
}
return ans;
}
};

剑指 Offer 35. 复杂链表的复制

待补

第三天 字符串(简单)

剑指 Offer 05. 替换空格

直接遍历

class Solution {
public:
string replaceSpace(string s) {
string ans;
for(auto i:s)
{
if(i==' ')
ans+="%20";
else
ans+=i;
}
return ans;
}
};

剑指 Offer 58 - II. 左旋转字符串

class Solution {
public:
string reverseLeftWords(string s, int n) {
string ans="";
ans+=s.substr(n,s.size());
ans+=s.substr(0,n);
return ans;
}
};

第 4 天 查找算法(简单)

剑指 Offer 03. 数组中重复的数字

构建元素的索引和值为一对一的关系,如果当前索引已经有值并且和当前值相同,则出现多次

class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int l=nums.size();
int i=0;
while(i<l)
{
if(nums[i]==i)
{
i++;
continue;
}
if(nums[nums[i]]==nums[i])
return nums[i];
swap(nums[i],nums[nums[i]]);
}
return -1;
}
};

剑指 Offer 53 - I. 在排序数组中查找数字 I

lower_boundupper_bound的使用

class Solution {
public:
int search(vector<int>& nums, int target) {
int l_place=lower_bound(nums.begin(),nums.end(),target)-nums.begin();
int r_place=upper_bound(nums.begin(),nums.end(),target)-nums.begin();
return r_place-l_place;
}
};

剑指 Offer 53 - II. 0~n-1中缺失的数字

遍历

class Solution {
public:
int missingNumber(vector<int>& nums) {
int l=nums.size();
for(int i=0;i<l;i++)
{
if(nums[i]!=i)
return i;
}
return l;
}
};

二分

class Solution {
public:
int missingNumber(vector<int>& nums) {
int l=0,r=nums.size()-1;
while(l<=r)
{
int mid=(l+r)/2;
if(nums[mid]>mid)
r=mid-1;
else
l=mid+1;
}
return l;
}
};

第 5 天 查找算法(中等)

剑指 Offer 04. 二维数组中的查找

二分

对每一行进行二分,时间复读\(O(n \log(m))\)

class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
for(auto i:matrix)
{
int place=lower_bound(i.begin(),i.end(),target)-i.begin();
if(place!=i.size()&&i[place]==target)
return true;
}
return false;
}
};

线性查找

从右上角开始,如果当前元素比target大,往左走;如果比target小,向下走。时间复杂度为\(O(n+m)\)

[font color="red"]注意数组为空的情况[/font]

class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
int n=matrix.size();
if(!n) return false;
int m=matrix[0].size();
int i=0,j=m-1;
while(i<n&&j>=0)
{
if(matrix[i][j]<target)
i++;
else if(matrix[i][j]>target)
j--;
else
return true;
}
return false;
}
};

剑指 Offer 11. 旋转数组的最小数字

遍历

class Solution {
public:
int minArray(vector<int>& numbers) {
int ans=numbers[0];
for(auto i:numbers)
ans=min(ans,i);
return ans;
}
};

二分

注意相等的情况,需要遍历

class Solution {
public:
int minArray(vector<int>& numbers) {
int l=0,r=numbers.size()-1;
int ans=10000000;
while(l<r)
{
int mid=(l+r)/2;
if(numbers[mid]>numbers[r])
l=mid+1;
else if(numbers[mid]<numbers[r])
r=mid;
else
{
for(int i=l;i<=r;i++)
ans=min(ans,numbers[i]);
return ans;
}
}
return numbers[l];
}
};

剑指 Offer 50. 第一个只出现一次的字符

直接用map存就行,可以把字符去一下重优化时间

class Solution {
public:
char firstUniqChar(string s) {
unordered_map<char,int>mp;
char ans=' ';
vector<char>v;
for(auto i:s)
{
if(!mp[i])
v.push_back(i);
mp[i]++;
}
for(auto i:v)
{
if(mp[i]==1)
return i;
}
return ans;
}
};

第 6 天 搜索与回溯算法(简单)

剑指 Offer 32 - I. 从上到下打印二叉树

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
queue<TreeNode*>que;
que.push(root);
vector<int>ans;
if(!root)
return ans;
while(!que.empty())
{
TreeNode *tmp=que.front();
que.pop();
if(tmp->left)
que.push(tmp->left);
if(tmp->right)
que.push(tmp->right);
ans.push_back(tmp->val);
}
return ans;
}
};

剑指 Offer 32 - II. 从上到下打印二叉树 II

在当前节点的下一层放入队列之前,把当前节点存下来

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root)
return {};
queue<TreeNode*>que;
que.push(root);
vector<vector<int> >ans;
while(!que.empty())
{
vector<int>tmp;
int sz=que.size();
for(int i=0;i<sz;i++)
{
TreeNode *now=que.front();
tmp.push_back(now->val);
que.pop();
if(now->left)
que.push(now->left);
if(now->right)
que.push(now->right);
}
ans.push_back(tmp);
}
return ans;
}
};

剑指 Offer 32 - III. 从上到下打印二叉树 III

和上一题一样,只不过在存入到最终结果之前需要判断一下当前在第几层,翻转一下

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root)
return {};
queue<TreeNode*>que;
que.push(root);
vector<vector<int> >ans;
while(!que.empty())
{
vector<int>tmp;
int sz=que.size();
for(int i=0;i<sz;i++)
{
TreeNode *now=que.front();
tmp.push_back(now->val);
que.pop();
if(now->left)
que.push(now->left);
if(now->right)
que.push(now->right);
}
if(ans.size()%2)
reverse(tmp.begin(),tmp.end());
ans.push_back(tmp);
}
return ans;
}
};

第 7 天 搜索与回溯算法(简单)

剑指 Offer 26. 树的子结构

先从A开始往下遍历,如果出现了与B的根节点相等的节点,开始A和B同时向下递归

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(!A||!B)
return false;
if(dfs(A,B))
return true;
return isSubStructure(A->left,B)||isSubStructure(A->right,B);
}
bool dfs(TreeNode *A,TreeNode *B)
{
if(!B)
return true;
if(!A)
return false;
if(A->val!=B->val)
return false;
return dfs(A->left,B->left)&&dfs(A->right,B->right);
}
};

剑指 Offer 27. 二叉树的镜像

BFS

用栈辅助遍历来实现二叉树的镜像

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if(!root)
return root;
stack<TreeNode*>st;
st.push(root);
while(!st.empty())
{
TreeNode *node=st.top();
st.pop();
if(node->left)
st.push(node->left);
if(node->right)
st.push(node->right);
TreeNode *tmp=node->left;
node->left=node->right;
node->right=tmp;
}
return root;
}
};

DFS

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if(!root)
return root;
TreeNode *node=root->left;
root->left=mirrorTree(root->right);
root->right=mirrorTree(node);
return root;
}
};

剑指 Offer 28. 对称的二叉树

对左子树和右子树同时向下遍历

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root)
return true;
return dfs(root->left,root->right);
}
bool dfs(TreeNode *A,TreeNode *B)
{
if(!A&&!B)
return true;
if((!A||!B)||A->val!=B->val)
return false;
return dfs(A->left,B->right)&&dfs(A->right,B->left);
}
};

第 8 天 动态规划(简单)

剑指 Offer 10- I. 斐波那契数列

别用递归写就行了

class Solution {
public:
int a[3];
const int mod=1e9+7;
int fib(int n) {
if(n<2)
return n;
a[0]=0;a[1]=1;
for(int i=2;i<=n;i++)
{
a[2]=(a[1]%mod+a[0]%mod)%mod;
a[0]=a[1];a[1]=a[2];
}
return a[2];
}
};

剑指 Offer 10- II. 青蛙跳台阶问题

\(dp[i]=dp[i-1]+dp[i-2]\)

class Solution {
public:
int dp[101];
const int mod=1e9+7;
int numWays(int n) {
dp[0]=1;
dp[1]=1;
dp[2]=2;
for(int i=2;i<=n;i++)
dp[i]=(dp[i-1]+dp[i-2])%mod;
return dp[n];
}
};

剑指 Offer 63. 股票的最大利润

不断更新当前元素与当前最小值的差值就行了

class Solution {
public:
int maxProfit(vector<int>& prices) {
int sz=prices.size();
if(!sz)
return 0;
int m=prices[0];
int ans=0;
for(int i=1;i<sz;i++)
{
m=min(prices[i],m);
ans=max(ans,prices[i]-m);
}
return ans;
}
};

LeetCode—剑指 Offer学习计划的更多相关文章

  1. 【剑指Offer学习】【全部面试题汇总】

    剑指Offer学习 剑指Offer这本书已经学习完了.从中也学习到了不少的东西,如今做一个总的文件夹.供自已和大家一起參考.学如逆水行舟.不进则退.仅仅有不断地学习才干跟上时候.跟得上技术的潮流! 全 ...

  2. 【剑指Offer学习】【所有面试题汇总】

    剑指Offer学习 剑指Offer这本书已经学习完了,从中也学习到了不少的东西,现在做一个总的目录,供自已和大家一起参考,学如逆水行舟,不进则退.只有不断地学习才能跟上时候,跟得上技术的潮流! 所有代 ...

  3. LeetCode剑指Offer刷题总结(一)

    LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...

  4. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  5. [leetcode] 剑指 Offer 专题(一)

    又开了一个笔记专题的坑,未来一两周希望能把<剑指Offer>的题目刷完

  6. 【剑指Offer学习】【面试题:二维数组中的查找】PHP实现

    最近一直看剑指Offer.里面很多算法题.于是就想着用PHP来显示一下. 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的 ...

  7. LeetCode 剑指 Offer 22. 链表中倒数第k个节点

    剑指 Offer 22. 链表中倒数第k个节点 题意 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点. ​ 例如,一个链表有 6 个 ...

  8. [LeetCode]剑指 Offer 17. 打印从1到最大的n位数

    输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数.比如输入 3,则打印出 1.2.3 一直到最大的 3 位数 999. 示例 1: 输入: n = 1 输出: [1,2,3,4,5,6,7, ...

  9. 【剑指Offer学习】【面试题55:字符流中第一个不反复的字符】

    题目:请实现一个函数用来找出字符流中第一个仅仅出现一次的字符. 举例说明 比如,当从字符流中仅仅读出前两个字符"go"时.第一个仅仅出现一次的字符是'g'.当从该字符流中读出前六个 ...

随机推荐

  1. OAuth2.0实战!使用JWT令牌认证!

    大家好,我是不才陈某~ 这是<Spring Security 进阶>的第3篇文章,往期文章如下: 实战!Spring Boot Security+JWT前后端分离架构登录认证! 妹子始终没 ...

  2. Ubuntu Linux安装QT5之旅

    1. QT 版本选择 如何选择QT版本,参考如下介绍 https://www.cnblogs.com/chinasoft/p/15226293.html 2.  在此以5.15.0解说 下载QT 版本 ...

  3. 大数据学习----day27----hive02------1. 分桶表以及分桶抽样查询 2. 导出数据 3.Hive数据类型 4 逐行运算查询基本语法(group by用法,原理补充) 5.case when(练习题,多表关联)6 排序

    1. 分桶表以及分桶抽样查询 1.1 分桶表 对Hive(Inceptor)表分桶可以将表中记录按分桶键(某个字段对应的的值)的哈希值分散进多个文件中,这些小文件称为桶. 如要按照name属性分为3个 ...

  4. CRLF漏洞浅析

    部分情况下,由于与客户端存在交互,会形成下面的情况 也就是重定向且Location字段可控 如果这个时候,可以向Location字段传点qqgg的东西 形成固定会话 但服务端应该不会存储,因为后端貌似 ...

  5. 容器之分类与各种测试(四)——unordered-multimap

    unordered-multiset与unordered-multimap的区别和multiset与multimap的区别基本相同,所以在定义和插入时需要注意 key-value 的类型. 例程 #i ...

  6. Android 利用Settings.Global属性跨应用定义标志位

    https://blog.csdn.net/ouzhuangzhuang/article/details/82258148 需求 需要在不同应用中定义一个标志位,这里介绍下系统级别的应用和非系统级别应 ...

  7. 锁对象-条件对象-synchronized关键字

    1 import java.util.concurrent.locks.Condition; 2 import java.util.concurrent.locks.Lock; 3 import ja ...

  8. js将数字转为千分位/清除千分位

    /** * 千分位格式化数字 * * @param s * 传入需要转换的数字 * @returns {String} */ function formatNumber(s) { if (!isNaN ...

  9. mybatis联合查询

    1.有学生实体 @Component @Scope("prototype") public class StudentInfo { private Integer studentI ...

  10. Python测试框架pytest入门基础

    Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.T ...