第 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. C#表格GridView显示2位百分比

    <asp:BoundField HeaderText="占比" DataField="number" DataFormatString="{0: ...

  2. 【每天五分钟大数据-第一期】 伪分布式+Hadoopstreaming

    说在前面 之前一段时间想着把 LeetCode 每个专题完结之后,就开始着手大数据和算法的内容. 想来想去,还是应该穿插着一起做起来. 毕竟,如果只写一类的话,如果遇到其他方面,一定会遗漏一些重要的点 ...

  3. Spark基础:(三)Spark 键值对操作

    1.pair RDD的简介 Spark为包含键值对类型的RDD提供了一些专有的操作,这些RDD就被称为pair RDD 那么如何创建pair RDD呢? 在不同的语言中有着不同的创建方式 在pytho ...

  4. 从面试官的角度,聊聊java面试流程

    在这篇回答里,就讲以我常规的面试流程为例,说下java方面大致会问什么问题,以及如何确认候选人达到招聘要求. 先说面试前准备,可能有些面试官是拿到简历直接问,而且是在候选人自我介绍时再草草浏览简历,但 ...

  5. 【J-Link】J-Link不支持(版本太低)

    事情起因,我原本可以烧录和仿真的(版本6.3.4),但是后来安装另一个东西,这个东西里面包含旧的J-Link驱动(版本5.1.2) 它把Keil文件夹下的JLinkARM.dll覆盖了,导致出现下面的 ...

  6. java多线程 并发编程

    一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种 ...

  7. 【Python】数据处理分析,一些问题记录

    不用造轮子是真的好用啊 python中单引号双引号的区别 和cpp不一样,cpp单引号表示字符,双引号表示字符串,'c'就直接是ascii值了 Python中单引号和双引号都可以用来表示一个字符串 单 ...

  8. 如何用three.js实现数字孪生、3D工厂、3D工业园区、智慧制造、智慧工业、智慧工厂-第十课

    文章前,先聊点啥吧. 最近元宇宙炒的挺火热,在所有人都争相定义元宇宙的时候,资本就开始着手入场了.当定义明确,全民皆懂之后,风口也就过去了. 前两天看到新闻,新世界CEO宣布购入最大的数字地块,这块虚 ...

  9. 02 - Vue3 UI Framework - 顶部边栏

    顶部边栏比较简单,而且首页和文档页都需要,所以我们先从顶部边栏做起 前文回顾点击 这里 返回阅读列表点击 这里 初始化 首先,在 components 文件夹下,创建一个 vue 组件,命名为 Top ...

  10. 分布式可扩展web体系结构设计实例分析

    Web分布式系统设计准则 下面以一个上传和查询图片的例子来说明分布式web结构的设计考虑和常用的提高性能的方法.该例子提供上传图片和下载图片两个简单功能,并且有一下假设条件?: - 可以存储无上限数量 ...