第 1 天 栈与队列(简单)

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

  1. class CQueue {
  2. public:
  3. CQueue() {
  4. }
  5. stack<int>s1,s2;
  6. void appendTail(int value) {
  7. s1.push(value);
  8. }
  9. int deleteHead() {
  10. if(s2.empty())
  11. {
  12. while(!s1.empty())
  13. {
  14. s2.push(s1.top());
  15. s1.pop();
  16. }
  17. }
  18. if(s2.empty())
  19. return -1;
  20. int tmp=s2.top();
  21. s2.pop();
  22. return tmp;
  23. }
  24. };
  25. /**
  26. * Your CQueue object will be instantiated and called as such:
  27. * CQueue* obj = new CQueue();
  28. * obj->appendTail(value);
  29. * int param_2 = obj->deleteHead();
  30. */

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

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

  1. class MinStack {
  2. public:
  3. /** initialize your data structure here. */
  4. MinStack() {
  5. }
  6. stack<int>st;
  7. stack<int>m;
  8. void push(int x) {
  9. st.push(x);
  10. if(m.empty()||m.top()>=x)
  11. m.push(x);
  12. }
  13. void pop() {
  14. if(st.top()==m.top())
  15. m.pop();
  16. st.pop();
  17. }
  18. int top() {
  19. return st.top();
  20. }
  21. int min() {
  22. return m.top();
  23. }
  24. };
  25. /**
  26. * Your MinStack object will be instantiated and called as such:
  27. * MinStack* obj = new MinStack();
  28. * obj->push(x);
  29. * obj->pop();
  30. * int param_3 = obj->top();
  31. * int param_4 = obj->min();
  32. */

第 2 天 链表(简单)

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

存入数组中然后反转一下

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * ListNode *next;
  6. * ListNode(int x) : val(x), next(NULL) {}
  7. * };
  8. */
  9. class Solution {
  10. public:
  11. vector<int> reversePrint(ListNode* head) {
  12. vector<int>v;
  13. while(head)
  14. {
  15. v.push_back(head->val);
  16. head=head->next;
  17. }
  18. reverse(v.begin(),v.end());
  19. return v;
  20. }
  21. };

剑指 Offer 24. 反转链表

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

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * ListNode *next;
  6. * ListNode(int x) : val(x), next(NULL) {}
  7. * };
  8. */
  9. class Solution {
  10. public:
  11. ListNode* reverseList(ListNode* head) {
  12. ListNode *cnt=head,*ans=NULL;
  13. while(cnt)
  14. {
  15. ListNode *tmp=cnt->next;
  16. cnt->next=ans;
  17. ans=cnt;
  18. cnt=tmp;
  19. }
  20. return ans;
  21. }
  22. };

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

待补

第三天 字符串(简单)

剑指 Offer 05. 替换空格

直接遍历

  1. class Solution {
  2. public:
  3. string replaceSpace(string s) {
  4. string ans;
  5. for(auto i:s)
  6. {
  7. if(i==' ')
  8. ans+="%20";
  9. else
  10. ans+=i;
  11. }
  12. return ans;
  13. }
  14. };

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

  1. class Solution {
  2. public:
  3. string reverseLeftWords(string s, int n) {
  4. string ans="";
  5. ans+=s.substr(n,s.size());
  6. ans+=s.substr(0,n);
  7. return ans;
  8. }
  9. };

第 4 天 查找算法(简单)

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

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

  1. class Solution {
  2. public:
  3. int findRepeatNumber(vector<int>& nums) {
  4. int l=nums.size();
  5. int i=0;
  6. while(i<l)
  7. {
  8. if(nums[i]==i)
  9. {
  10. i++;
  11. continue;
  12. }
  13. if(nums[nums[i]]==nums[i])
  14. return nums[i];
  15. swap(nums[i],nums[nums[i]]);
  16. }
  17. return -1;
  18. }
  19. };

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

lower_boundupper_bound的使用

  1. class Solution {
  2. public:
  3. int search(vector<int>& nums, int target) {
  4. int l_place=lower_bound(nums.begin(),nums.end(),target)-nums.begin();
  5. int r_place=upper_bound(nums.begin(),nums.end(),target)-nums.begin();
  6. return r_place-l_place;
  7. }
  8. };

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

遍历

  1. class Solution {
  2. public:
  3. int missingNumber(vector<int>& nums) {
  4. int l=nums.size();
  5. for(int i=0;i<l;i++)
  6. {
  7. if(nums[i]!=i)
  8. return i;
  9. }
  10. return l;
  11. }
  12. };

二分

  1. class Solution {
  2. public:
  3. int missingNumber(vector<int>& nums) {
  4. int l=0,r=nums.size()-1;
  5. while(l<=r)
  6. {
  7. int mid=(l+r)/2;
  8. if(nums[mid]>mid)
  9. r=mid-1;
  10. else
  11. l=mid+1;
  12. }
  13. return l;
  14. }
  15. };

第 5 天 查找算法(中等)

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

二分

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

  1. class Solution {
  2. public:
  3. bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
  4. for(auto i:matrix)
  5. {
  6. int place=lower_bound(i.begin(),i.end(),target)-i.begin();
  7. if(place!=i.size()&&i[place]==target)
  8. return true;
  9. }
  10. return false;
  11. }
  12. };

线性查找

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

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

  1. class Solution {
  2. public:
  3. bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
  4. int n=matrix.size();
  5. if(!n) return false;
  6. int m=matrix[0].size();
  7. int i=0,j=m-1;
  8. while(i<n&&j>=0)
  9. {
  10. if(matrix[i][j]<target)
  11. i++;
  12. else if(matrix[i][j]>target)
  13. j--;
  14. else
  15. return true;
  16. }
  17. return false;
  18. }
  19. };

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

遍历

  1. class Solution {
  2. public:
  3. int minArray(vector<int>& numbers) {
  4. int ans=numbers[0];
  5. for(auto i:numbers)
  6. ans=min(ans,i);
  7. return ans;
  8. }
  9. };

二分

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

  1. class Solution {
  2. public:
  3. int minArray(vector<int>& numbers) {
  4. int l=0,r=numbers.size()-1;
  5. int ans=10000000;
  6. while(l<r)
  7. {
  8. int mid=(l+r)/2;
  9. if(numbers[mid]>numbers[r])
  10. l=mid+1;
  11. else if(numbers[mid]<numbers[r])
  12. r=mid;
  13. else
  14. {
  15. for(int i=l;i<=r;i++)
  16. ans=min(ans,numbers[i]);
  17. return ans;
  18. }
  19. }
  20. return numbers[l];
  21. }
  22. };

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

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

  1. class Solution {
  2. public:
  3. char firstUniqChar(string s) {
  4. unordered_map<char,int>mp;
  5. char ans=' ';
  6. vector<char>v;
  7. for(auto i:s)
  8. {
  9. if(!mp[i])
  10. v.push_back(i);
  11. mp[i]++;
  12. }
  13. for(auto i:v)
  14. {
  15. if(mp[i]==1)
  16. return i;
  17. }
  18. return ans;
  19. }
  20. };

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

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

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. vector<int> levelOrder(TreeNode* root) {
  13. queue<TreeNode*>que;
  14. que.push(root);
  15. vector<int>ans;
  16. if(!root)
  17. return ans;
  18. while(!que.empty())
  19. {
  20. TreeNode *tmp=que.front();
  21. que.pop();
  22. if(tmp->left)
  23. que.push(tmp->left);
  24. if(tmp->right)
  25. que.push(tmp->right);
  26. ans.push_back(tmp->val);
  27. }
  28. return ans;
  29. }
  30. };

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

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

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. vector<vector<int>> levelOrder(TreeNode* root) {
  13. if(!root)
  14. return {};
  15. queue<TreeNode*>que;
  16. que.push(root);
  17. vector<vector<int> >ans;
  18. while(!que.empty())
  19. {
  20. vector<int>tmp;
  21. int sz=que.size();
  22. for(int i=0;i<sz;i++)
  23. {
  24. TreeNode *now=que.front();
  25. tmp.push_back(now->val);
  26. que.pop();
  27. if(now->left)
  28. que.push(now->left);
  29. if(now->right)
  30. que.push(now->right);
  31. }
  32. ans.push_back(tmp);
  33. }
  34. return ans;
  35. }
  36. };

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

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

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. vector<vector<int>> levelOrder(TreeNode* root) {
  13. if(!root)
  14. return {};
  15. queue<TreeNode*>que;
  16. que.push(root);
  17. vector<vector<int> >ans;
  18. while(!que.empty())
  19. {
  20. vector<int>tmp;
  21. int sz=que.size();
  22. for(int i=0;i<sz;i++)
  23. {
  24. TreeNode *now=que.front();
  25. tmp.push_back(now->val);
  26. que.pop();
  27. if(now->left)
  28. que.push(now->left);
  29. if(now->right)
  30. que.push(now->right);
  31. }
  32. if(ans.size()%2)
  33. reverse(tmp.begin(),tmp.end());
  34. ans.push_back(tmp);
  35. }
  36. return ans;
  37. }
  38. };

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

剑指 Offer 26. 树的子结构

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

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. bool isSubStructure(TreeNode* A, TreeNode* B) {
  13. if(!A||!B)
  14. return false;
  15. if(dfs(A,B))
  16. return true;
  17. return isSubStructure(A->left,B)||isSubStructure(A->right,B);
  18. }
  19. bool dfs(TreeNode *A,TreeNode *B)
  20. {
  21. if(!B)
  22. return true;
  23. if(!A)
  24. return false;
  25. if(A->val!=B->val)
  26. return false;
  27. return dfs(A->left,B->left)&&dfs(A->right,B->right);
  28. }
  29. };

剑指 Offer 27. 二叉树的镜像

BFS

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

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. TreeNode* mirrorTree(TreeNode* root) {
  13. if(!root)
  14. return root;
  15. stack<TreeNode*>st;
  16. st.push(root);
  17. while(!st.empty())
  18. {
  19. TreeNode *node=st.top();
  20. st.pop();
  21. if(node->left)
  22. st.push(node->left);
  23. if(node->right)
  24. st.push(node->right);
  25. TreeNode *tmp=node->left;
  26. node->left=node->right;
  27. node->right=tmp;
  28. }
  29. return root;
  30. }
  31. };

DFS

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. TreeNode* mirrorTree(TreeNode* root) {
  13. if(!root)
  14. return root;
  15. TreeNode *node=root->left;
  16. root->left=mirrorTree(root->right);
  17. root->right=mirrorTree(node);
  18. return root;
  19. }
  20. };

剑指 Offer 28. 对称的二叉树

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

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. bool isSymmetric(TreeNode* root) {
  13. if(!root)
  14. return true;
  15. return dfs(root->left,root->right);
  16. }
  17. bool dfs(TreeNode *A,TreeNode *B)
  18. {
  19. if(!A&&!B)
  20. return true;
  21. if((!A||!B)||A->val!=B->val)
  22. return false;
  23. return dfs(A->left,B->right)&&dfs(A->right,B->left);
  24. }
  25. };

第 8 天 动态规划(简单)

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

别用递归写就行了

  1. class Solution {
  2. public:
  3. int a[3];
  4. const int mod=1e9+7;
  5. int fib(int n) {
  6. if(n<2)
  7. return n;
  8. a[0]=0;a[1]=1;
  9. for(int i=2;i<=n;i++)
  10. {
  11. a[2]=(a[1]%mod+a[0]%mod)%mod;
  12. a[0]=a[1];a[1]=a[2];
  13. }
  14. return a[2];
  15. }
  16. };

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

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

  1. class Solution {
  2. public:
  3. int dp[101];
  4. const int mod=1e9+7;
  5. int numWays(int n) {
  6. dp[0]=1;
  7. dp[1]=1;
  8. dp[2]=2;
  9. for(int i=2;i<=n;i++)
  10. dp[i]=(dp[i-1]+dp[i-2])%mod;
  11. return dp[n];
  12. }
  13. };

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

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

  1. class Solution {
  2. public:
  3. int maxProfit(vector<int>& prices) {
  4. int sz=prices.size();
  5. if(!sz)
  6. return 0;
  7. int m=prices[0];
  8. int ans=0;
  9. for(int i=1;i<sz;i++)
  10. {
  11. m=min(prices[i],m);
  12. ans=max(ans,prices[i]-m);
  13. }
  14. return ans;
  15. }
  16. };

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. day11 四层负载均衡和http协议

    day11 四层负载均衡和http协议 四层负载均衡和七层负载均衡的区别 四层和七层负载均衡的区别 四层负载均衡数据包在底层就进行了分发,而七层负载均衡数据包则是在最顶层进行分发.由此可以看出,七层负 ...

  2. 【Penetration】红日靶场(一)

    nmap探查存活主机 nmap -sP 10.10.2.0/24 图片: https://uploader.shimo.im/f/cfuQ653BEvyA42FR.png!thumbnail?acce ...

  3. Linux磁盘分区(四)之分区大小调整

    Linux磁盘分区(四)之分区大小调整在学习调整分区大小之前,先了解linx分区的概念.参考如下博客:[1]linux 分区 物理卷 逻辑卷 https://www.cnblogs.com/liuch ...

  4. 【TCP/IP】之Java socket编程API基础

    Socket是Java网络编程的基础,深入学习socket对于了解tcp/ip网络通信协议很有帮助, 此文讲解Socket的基础编程.Socket用法:①.主要用在进程间,网络间通信. 文章目录如下: ...

  5. C语言编辑链接

    库函数(Library Files)库函数就是函数的仓库,它们都经过编译,重用性不错.通常,库函数相互合作,来完成特定的任务.比如操控屏幕的库函数(cursers和ncursers库函数),数据库读取 ...

  6. Oracle 用户自定义数据类型

    用户自定义数据类型(User-defined Data Type)oracle支持对象类型(Object Type).嵌套类型(Nested Table Type)和可变数组类型(Varray Dat ...

  7. 数据库系统相关SQL

    杀进程 查出所有被锁住的表 select b.owner TABLEOWNER, b.object_name TABLENAME, c.OSUSER LOCKBY, c.USERNAME LOGINI ...

  8. java关键字volatile内存语义详细分析

    volatile变量自身具有下列特性. 1.可见性.对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写 入. · 2.原子性:对任意单个volatile变量的读/ ...

  9. 创建线程的第二种方式------实现Runnable接口的方式

    package cn.itcast.demo16.Demo07.Runnable;/** * @author newcityman * @date 2019/7/22 - 23:17 */public ...

  10. vue cli3.0 首次加载优化

    项目经理要求做首页加载优化,打包后从十几兆优化到两兆多,记下来怕下次忘记 运行report脚本 可看到都加载了那些内容,在从dist文件中index.html 查看首次加载都加载了那些东西,如下图:然 ...