![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
剑指offer
C++实现剑指offer的问题
Everglow—
这个作者很懒,什么都没留下…
展开
-
剑指offer 40:最小的K个数
思路topK问题想到使用堆数据结构解决, 最小的K个数要维护一个大根堆,大根堆的元素有K个class Solution {public: vector<int> getLeastNumbers(vector<int>& arr, int k) { priority_queue<int> q; vector<int> res; if(k == 0) return res; f.原创 2021-03-03 13:27:36 · 94 阅读 · 0 评论 -
剑指offer 24:反转链表
方法一:定义pre节点和cur节点,记得将cur节点的next暂存,迭代的将节点一个一个反转。class Solution {public: ListNode* reverseList(ListNode* head) { if(!head || !head->next) return head; ListNode* pre = nullptr; ListNode* cur = head; while (cur) { .原创 2021-03-02 20:02:48 · 77 阅读 · 0 评论 -
剑指offer 53:0~n-1中缺失的数字
class Solution {public: int missingNumber(vector<int>& nums) { int l = 0, r = nums.size() - 1; while (l <= r) { int mid = (l+r) >> 1 ; if(nums[mid] == mid) l = mid + 1; else r = m.原创 2021-02-27 12:07:15 · 89 阅读 · 0 评论 -
剑指offer 53:在排序数组中查找数字
思路二次二分查找,查找target的右边界和target-1的右边界。target-1存在与否不影响边界的查找,可以理解成搜索插入位置。二者相减即为target出现的次数class Solution {public: int rightBound(vector<int>& nums, int target) { int l = 0, r = nums.size() - 1; while (l <= r) { i.原创 2021-02-27 11:34:20 · 82 阅读 · 0 评论 -
剑指offer 52:两个链表的第一个公共节点
两个链表互相走过对方的路,就相遇了A: a1->a2->c1->c2->c3->b1->b2->b3->c1B: b1->b2->b3->c1->c2->c3->a1->a2->c1如果不相交,两个链表也会相遇在NULLclass Solution {public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) .原创 2021-02-26 23:38:26 · 122 阅读 · 0 评论 -
剑指offer 54:二叉搜索树的第k大节点
思路二叉搜索树的中序遍历就是将所有节点从小到大排列,那么如果是从大到小排列,第k个节点就是第k大的节点了。因此在中序遍历的过程中只要先遍历右子树,后遍历左子树即可。class Solution {private: int count = 0, res = 0;public: void inorder(TreeNode* root, int k) { if (root == nullptr) return; inorder(root->right.原创 2021-02-25 23:37:27 · 113 阅读 · 0 评论 -
剑指offer 68:二叉搜索树的最近公共祖先
思路从上往下遍历,只要root在p,q之间就说明root是最近公共祖先。class Solution {public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { while(root) { if (root->val > p->val && root->val > q->val) { .原创 2021-02-25 18:51:35 · 73 阅读 · 0 评论 -
剑指offer 68:二叉树的最近公共祖先
思路从两个叶子节点往父节点找,后序遍历很适合。注意递归逻辑中的四个逻辑判断。class Solution {public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (root == q || root == p || root == nullptr) return root; TreeNode* left = lowestCommonAncesto原创 2021-02-25 18:21:32 · 91 阅读 · 0 评论 -
剑指offer 55:平衡二叉树
思路核心思想就是在dfs的过程中维护一个全局变量来判断是否为平衡二叉树class Solution {private: bool balanced = true; int dfs(TreeNode* root) { if (root == nullptr) return 0; int left = dfs(root->left); int right = dfs(root->right); if (abs(r.原创 2021-02-25 16:15:48 · 79 阅读 · 0 评论 -
剑指offer 58:左旋转字符串
class Solution {public: string reverseLeftWords(string s, int n) { reverse(s.begin(), s.begin()+n); reverse(s.begin()+n, s.end()); reverse(s.begin(), s.end()); return s; }};原创 2021-02-25 15:57:38 · 73 阅读 · 0 评论 -
剑指offer 60:n个骰子的点数
class Solution {public: vector<double> dicesProbability(int n) { vector<double> res(n * 6 - n + 1); vector<vector<int> > dp(n + 1, vector<int>(6 * n + 1, 0)); // 将全部值初始化为 0 int row = dp.size(), co原创 2021-02-25 12:06:11 · 89 阅读 · 0 评论 -
剑指offer 61:扑克牌中的顺子
思路先将数组排序,遍历数组将0的个数记录下来,因为一个0可以补充一个数,举例:如果两个连续的数是5和8,就需要2个0来补充,如果0不够了直接返回false,如果能顺利的遍历完数组,证明抽出的扑克牌是顺子。class Solution {public: bool isStraight(vector<int>& nums) { sort(nums.begin(), nums.end()); int zero = 0; for (.原创 2021-02-25 00:23:33 · 73 阅读 · 0 评论 -
剑指offer 62:圆圈中最后剩下的数字
class Solution {public: int lastRemaining(int n, int m) { if (n == 1) return 0; return (m%n + lastRemaining(n-1, m)) % n; }};原创 2021-02-24 22:14:17 · 64 阅读 · 0 评论 -
剑指offer 63:股票的最大利润
思路与其说是动态规划,倒不如说是贪心。class Solution {public: int maxProfit(vector<int>& prices) { int res = 0; int minPrice = INT_MAX; for (int price : prices) { minPrice = min(minPrice, price); res = max(res.原创 2021-02-24 21:41:33 · 81 阅读 · 0 评论 -
剑指offer 64:求1+2+...+n
思路递归可以很好的解决问题但是递归一定要有出口,出口就要使用条件判断语句,与题目不符。可以使用&&运算符的特性:对于表达式a&&b,如果a不为假,那么不会运行b部分的代码,可以用来跳出递归class Solution {public: int sumNums(int n) { n && (n += sumNums(n - 1)); return n; }};...原创 2021-02-24 19:30:25 · 96 阅读 · 0 评论 -
剑指offer 65:不用加减乘除做加法
思路数的运算只有四则运算和位运算,题目不允许进行四则运算,只有通过位运算进行求解。无进位和 与 异或运算 规律相同,进位 和 与运算 规律相同(并需左移一位)先求异或,进位为与,进位加上异或值为最后的结果,迭代求出即可!C++中负数不能左移,注意转换成unsigned int!class Solution {public: int add(int a, int b) { int sum = 0, carry = 0; while(b) { .原创 2021-02-24 18:39:00 · 76 阅读 · 0 评论 -
剑指offer 66:构建乘积数组
思路使用二个dp数组分别维护i左侧的乘积和i右侧的乘积class Solution {public: vector<int> constructArr(vector<int>& a) { int n = a.size(); vector<int> res(n), dpl(n, 1), dpr(n, 1); for (int i = 1; i < n; ++i) { dpl.原创 2021-02-24 18:13:39 · 67 阅读 · 0 评论 -
剑指offer 57:和为s的两个数字
思路定义首指针和尾指针向中间遍历即可class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { int p1=0; int p2=nums.size()-1; while(p1!=p2) { if(nums[p1]+nums[p2]==target) return vector<int>.原创 2021-02-24 17:34:33 · 50 阅读 · 0 评论 -
剑指offer 34:二叉树中和为某一值的路径
class Solution {public: vector<vector<int>> res; vector<int> path; void dfs(TreeNode* root, vector<int> path, int targetSum) { if (root == nullptr) return; path.push_back(root->val); if (root.原创 2021-02-24 16:26:33 · 68 阅读 · 0 评论 -
剑指offer 55:二叉树的深度
思路DFS,二叉树的后序遍历,先求左子树最大深度,再求右子树最大深度,左右子树最大深度加一即为二叉树最大深度。class Solution {public: int maxDepth(TreeNode* root) { if (root == nullptr) return 0; return 1 + max(maxDepth(root->left), maxDepth(root->right)); }};...原创 2021-02-24 12:02:14 · 72 阅读 · 0 评论 -
剑指offer 50:第一个只出现一次的字符
思路遍历两次数组,第一次用hashtable存储出现次数,第二次找出value值为1的第一个数。对于字母类问题hashtable处理,使用数组作为hashtable其实效率更高。在这里我直接用hashtable了。class Solution {public: char firstUniqChar(string s) { unordered_map<char, int> map; for (auto c : s) { map.原创 2021-02-24 11:55:15 · 51 阅读 · 0 评论 -
剑指offer 44:数字序列中某一位的数字
代码来源于leetcode上的一个高亮题解class Solution {public: int findNthDigit(int n) { if(n == 0) {return 0;} int digit = 1; // 数位(个位/十位/百位/...,就是1/2/3/...) long start = 1; // 属于该数位的所有数的起始点数(个位是1,十位是10,百位是100) long index_count = dig.原创 2021-02-24 10:37:03 · 69 阅读 · 0 评论 -
剑指offer 32:从上到下打印二叉树 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>>.原创 2021-02-23 23:56:30 · 78 阅读 · 0 评论 -
剑指offer 32:从上到下打印二叉树 I
思路二叉树的层序遍历。。。class Solution {public: vector<int> levelOrder(TreeNode* root) { queue<TreeNode*> que; vector<int> res; if (root != nullptr) que.push(root); while (!que.empty()) { TreeNode*.原创 2021-02-23 21:28:18 · 54 阅读 · 0 评论 -
剑指offer 39:数组中出现次数超过一半的数字
方法一:哈希表使用hashtable统计次数,返回超过数组长度一半的数字。class Solution {public: int majorityElement(vector<int>& nums) { unordered_map<int, int> count; for (auto n : nums) { count[n]++; } for (auto m : count.原创 2021-02-23 18:01:25 · 59 阅读 · 0 评论 -
剑指offer面试题29:顺时针打印矩阵
class Solution {public: vector<int> spiralOrder(vector<vector<int>>& matrix) { if(matrix.empty() || matrix[0].size() == 0) return vector<int>(); vector<int> res; int rows=matrix.size(); .原创 2020-10-14 23:54:38 · 108 阅读 · 0 评论 -
剑指offer面试题30:包含min函数的栈
class MinStack {public: stack<int> s1; stack<int> s2; MinStack() { } void push(int x) { s1.push(x); if(s2.empty()) s2.push(x); else if(s2.top()<x) s2.push(s2.top()); else s2.push(x).原创 2020-10-07 19:02:31 · 77 阅读 · 0 评论 -
剑指offer面试题28:对称的二叉树
class Solution {public: bool isSymmetric(TreeNode* root) { if(!root) return true; return isMirror(root->left,root->right); } bool isMirror(TreeNode* node1,TreeNode* node2) { if(!node1&&!node2) return true.原创 2020-10-07 16:18:22 · 61 阅读 · 0 评论 -
剑指offer面试题27:二叉树的镜像
class Solution {public: TreeNode* mirrorTree(TreeNode* root) { if(!root||(!root->left&&!root->right)) return root; swapNode(root); mirrorTree(root->left); mirrorTree(root->right); return roo.原创 2020-10-06 16:19:14 · 59 阅读 · 0 评论 -
剑指offer面试题26:树的子结构
思路:二叉树问题大多数都可以使用递归解决,判断B是否为A的子结构可以考虑对A进行递归遍历,当A某个节点与B头节点相同时,调用函数判断B是否包含在A内。代码如下:包含两个递归过程,第一个递归过程用来遍历A树,第二个递归用来判断B是否在A内。class Solution {public: bool isSubStructure(TreeNode* A, TreeNode* B) { if(!A||!B) return false; bool res = false;.原创 2020-10-06 15:22:45 · 64 阅读 · 0 评论 -
剑指offer面试题24:反转链表
cur是当前操作的节点class Solution {public: ListNode* reverseList(ListNode* head) { if(!head||!head->next) return head; ListNode* pre=nullptr; ListNode* cur=head; while(cur) { ListNode* temp=cur->next; .原创 2020-09-25 16:15:57 · 54 阅读 · 0 评论 -
剑指offer面试题25:合并两个排序的列表
注:链表是挂在新建节点的后面class Solution {public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(!l1) return l2; if(!l2) return l1; ListNode* dummy=new ListNode(-1); ListNode* cur=dummy; while(l1&&l2) {.原创 2020-09-24 09:09:53 · 64 阅读 · 0 评论 -
剑指offer面试题18:删除链表的节点
方法一:指针遍历class Solution {public: ListNode* deleteNode(ListNode* head, int val) { ListNode* dummy=new ListNode(-1); dummy->next=head; ListNode* cur=dummy; while(cur->next) { if(cur->next->val==val原创 2020-09-22 14:42:15 · 89 阅读 · 1 评论 -
剑指offer面试题22:链表中倒数第k个结点
class Solution {public: ListNode* getKthFromEnd(ListNode* head, int k) { ListNode* cur=head; for(int i=0;i<k;i++) { cur=cur->next; } while(cur) { head=head->next; cur=cur-&g.原创 2020-09-17 22:10:54 · 89 阅读 · 0 评论 -
剑指offer面试题14-II:剪绳子
使用动态规划方法会造成溢出的情况,因此可以使用贪心算法,同理剪绳子I也可以使用贪心解决。使用贪心就要尽可能凑出长度为3的绳子,但是当最后的绳子长度为4时就不要再进行拆分了。原创 2020-09-17 15:40:22 · 92 阅读 · 0 评论 -
剑指offer面试题14-I:剪绳子
dp数组记录的是最大值,但是2,3这种特殊情况返回的并非最大值,在dp中,2,3可以不拆分class Solution {public: int cuttingRope(int n) { if(n<=3) return n-1; vector<int> dp(n+1,0); dp[0]=0; dp[1]=1; dp[2]=2; dp[3]=3; int temp=0.原创 2020-09-16 21:58:46 · 59 阅读 · 0 评论 -
剑指offer面试题10-II:青蛙跳台阶问题
class Solution {public: int numWays(int n) { if(n==0||n==1) return 1; if(n==2) return 2; int a=1,b=2; for(int i=3;i<=n;i++) { int tmp=b; b=(a+b)%1000000007; a=tmp; } .原创 2020-09-01 14:17:42 · 75 阅读 · 0 评论 -
剑指offer面试题09:用两个栈实现队列
准备两个栈,一个push栈,一个pop栈。appendTail操作始终是向push栈中push元素,deleteHead操作始终是从pop栈pop元素,要求pop栈是从push倒过来,pop只要有元素,push就不倒。class CQueue {private: stack<int> Spush,Spop;public: CQueue() { } void appendTail(int value) { Spush.push(va原创 2020-08-31 09:48:07 · 72 阅读 · 0 评论 -
剑指offer面试题06:从尾到头打印链表
题目中涉及逆序首先想到的是栈结构,本题可以额外使用一个栈保存结果再弹出到数组,但是使用数组保存再进行reverse操作会降低空间复杂度class Solution {public: vector<int> reversePrint(ListNode* head) { vector<int> res; ListNode* cur=head; while(cur) { res.push_back(cur.原创 2020-08-28 15:35:46 · 76 阅读 · 0 评论 -
剑指offer面试题05:替换空格
不重新开辟新字符串,直接在原字符串进行修改的方法class Solution {public: string replaceSpace(string s) { if(s.empty()) return s; int count=0; for(int i=0;i<s.size();i++) { if(s[i]==' ') count++; } int ori=s.size()-1; .原创 2020-08-27 21:43:22 · 71 阅读 · 0 评论