剑指Offer
剑指Offer算法
IT奶牛
真困啊
展开
-
LeetCode 剑指 Offer 64. 求1+2+…+n
原题链接 短路效应的应用 本题使用递归结构,一般递归结束条件为: if(n <= 1) return 1; 这里可以换成 等价的布尔判断,当 n > 1 的条件 不满足时候,递归此时自动返回,返回层执行return 。 本题代码: class Solution { public: int res = 0; int sumNums(int n) { n > 1 && sumNums(n -1); res += n;原创 2021-03-02 13:49:01 · 70 阅读 · 0 评论 -
LeetCode 剑指 Offer 30. 包含min函数的栈
原题链接 使用双栈实现包含min函数的单栈,其中一个站用于维护当前栈内的最小排序元素。 class MinStack { public: /** initialize your data structure here. */ MinStack() { while(!mystack.empty()) mystack.pop(); while(!minStack.empty()) minStack.pop(); } void push(i原创 2021-03-02 13:22:19 · 65 阅读 · 0 评论 -
LeetCode 剑指 Offer 59 - I. 滑动窗口的最大值
原题链接 思路:暴力解法和双端队列。 暴力解法:窗口每次移动都去找当前窗口内的最大值。 双端队列:存储元素的的下标,队列中下标的对应元素是从大到小的顺讯,并按时判断当前队列中的最大值是否还在窗口内。 暴力解法: /** * Note: The returned array must be malloced, assume caller calls free(). */ int maxInt(int* nums, int left, int numsSize){ int max = -1000原创 2020-12-13 21:24:14 · 72 阅读 · 0 评论 -
LeetCode 剑指 Offer 40. 最小的k个数
原题链接 思路: 利用快排的思想,找到能够区分 k 个 和 n-k 个元素的轴值下标k,输出前 k个元素即可。 代码分三部分写,分段、判断分段结果函数、初始函数。 注意的地方是 partition 函数中判断是否要继续 --right 或者 ++left 的条件中,轴值与数组元素需要至少保持一个有等于的情况,如果两个判断都没有等于的情况,那么会造成无限循环。原因是,如果在等于轴值的地方内层第一个 while 循环退出,在会把 nums[left] 位置的值换成轴值,相应的内层下一个 while 则不进入,原创 2020-12-13 17:54:35 · 75 阅读 · 0 评论 -
LeetCode 剑指 Offer 61. 扑克牌中的顺子
原题链接 思路: 最大值与最小值不能超过4; 不能出现除0之外的重复数字。 bool isStraight(int* nums, int numsSize){ int arr[14] = {0}; // 来个桶统计元素数量 int maxNum = -1, minNum = 14; for(int i =0; i < numsSize; i++){ if(nums[i] != 0){ //元素不为 0 时候统计 arr[nums[原创 2020-12-13 15:15:08 · 83 阅读 · 0 评论 -
LeetCode 剑指 Offer 62. 圆圈中最后剩下的数字
约瑟夫环问题。 思路:一个一个杀掉,再逆向补回来还原位置。 参考解释 int lastRemaining(int n, int m){ int pos = 0; for(int i = 2; i <= n; i++){ pos = (pos + m) % i; } return pos; }原创 2020-12-06 17:21:13 · 97 阅读 · 0 评论 -
LeetCode 剑指 Offer 54. 二叉搜索树的第k大节点
思路: 开辟数组; 中序遍历; 索引找值。 换成C语言风格。 要不然太依赖STL了。 /** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ void dfs(struct TreeNode* root, int* count, int* returnSize){原创 2020-12-06 16:52:25 · 105 阅读 · 0 评论 -
LeetCode 剑指 Offer 11. 旋转数组的最小数字
原题链接 一道简单题,求旋转数组的最小值。 无疑二分法是比较容易想到的。 使用了递归结构容易理解,不同很多额外的判断。 当然这种解法实际上没有利用旋转数组的特点,对于一般数组也是适用的。 技巧性的东西就是在判断搞下标的时候用了取余防止溢出。 时间复杂度是O(log n),空间复杂度是O(n) int minArray(int* numbers, int numbersSize){ if(numbersSize == 1) return *numbers; if(numbersSize ==原创 2020-11-29 18:52:39 · 73 阅读 · 0 评论 -
LeetCode 剑指 Offer 68 - II. 二叉树的最近公共祖先
原题链接 之前做了二叉搜索树的最近公共祖先寻找,因为搜索树的有序性,很好做。但是这个题换成了一般二叉树,递归上略微复杂。 看了评论里面大神的杰作,实在太nb了嗷。本质上和我的想法是一样的,都是在看目标节点是否在根节点的左右子树中,注意返回值的写法,判断结构 A ? B : C 其中的 B 和C是可以嵌套使用该结构的,学到了。 给出代码: struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struc原创 2020-11-29 17:46:47 · 110 阅读 · 0 评论 -
LeetCode 剑指 Offer 28. 对称的二叉树
原题链接 一道思路比较清晰的题目。 关于树的处理,第一想到的就是递归咯。 思路: 想要比较左右是否对称,遍历。 一般的中序遍历是从左子节点到根节点再到右子节点,根据这个,我们对称地,先遍历右子节点,再遍历根节点,最后遍历左子节点。 得到两个遍历数组,然后比较这两个数组中的结果。 时间复杂度是O(n),空间复杂度为O(n). 给出代码: /** * Definition for a binary tree node. * struct TreeNode { * int val; *原创 2020-11-29 15:07:23 · 75 阅读 · 1 评论 -
LeetCode 剑指 Offer 42. 连续子数组的最大和
原题链接 经典求最大子数组和题目。 当然是使用最好的动态规划了,题目比较简单,但是记录一下,算是对动态规划问题的入门学习理解。 思路: dp[i] 中保留了以当前元素为最后一个元素的数组的最大子数组和。(这里相当于是在参数传入的数组上直接操作。 前后联系起来的关键是“连续”,即:如果前面的一个元素 dp[i-1] 使得自己与后面一个元素 dp[i] 的和变小,那么他肯定不被包含在和最大的子数组中,如果以 dp[i] 开头的数组可能是最大子数组,重新开始算和。即 dp[i-1] <= 0; 如果 d原创 2020-11-22 16:33:02 · 81 阅读 · 0 评论 -
LeetCode 剑指 Offer 10- II. 青蛙跳台阶问题
原题链接 思路: 斐波那契数列思想,f(n) = f(n-1) + f(n-2)。 注意起始条件为f(0) = 1, f(1) = 1; 看热评解释吧,嘿嘿 代码: class Solution { public: int numWays(int n) { if(n ==1 || n == 0) return 1; int a = 1, b = 1, i = 0; int sum = 0; while(i <= n-2){原创 2020-11-22 15:20:50 · 65 阅读 · 0 评论 -
LeetCode 剑指 Offer 65. 不用加减乘除做加法
原题链接 思路:不让使用一般加减运算符号当然是想到位运算。 int 类型数在计算机中是使用补码存放,负数正数的加减规则一样,在计算的时候把有符号数看做无符号数计算,不然会报负值左移错误。 两个二进制数异或运算得到每一位进位以后剩下的,例如:二进制1与1异或,结果是二进制10,剩下的0。这一步结果是 ax。 两个二进制数与运算得到结果,表示这一位是否产生进位,如果产生进位,进位对应的是更高一位,对齐的操作是让二进制数左移一位。这一步结果是 bx。 然后再把 ax 和 bx 相加,重复操作2、操作3。 结束的原创 2020-11-22 14:17:19 · 196 阅读 · 0 评论 -
LeetCode 剑指 Offer 07. 重建二叉树
原题链接 思路: 根据前序遍历和后续遍历的原理,对数组进行划分,使用递归结构解决构建树的问题。 前序遍历的第一个元素是该数组构成树的根节点,在中序遍历中找到该元素,左边即为该根节点的左子树,右边为该根节点的右子树。 记录中序序列中左子树节点数,在前序序列中根据该数目得到左子树的前序序列和右子树序列。在中序序列中得到左子树的中序序列和右子树的中序序列。 对这两部分使用递归。 递归边界是子树为空。 给出代码: /** * Definition for a binary tree node. * str原创 2020-11-15 16:47:11 · 76 阅读 · 0 评论 -
LeetCode 剑指 Offer 39. 数组中出现次数超过一半的数字
原题链接 本是一道简单题,但是涉及到一个比较好的解题思路摩尔投票算法 大体的思路就是一个相同的数字和另一个不同的数字同归于尽,最后剩下的定是数量超过半数的。 给出代码: class Solution { public: int majorityElement(vector<int>& nums) { int moleVotes = 0, result = 0; for(int i : nums){ if(moleVotes原创 2020-11-01 15:40:08 · 843 阅读 · 0 评论 -
LeetCode 剑指 Offer 35. 复杂链表的复制
原题链接 思路: 这道题直观的看起来甚至不需要什么算法,就按照一般的复制思路,新开辟空间,然后把对应的节点的值抄过去,先不看random。 令人头疼的是Node->random是随意指向的,没有什么规律可以遵循。 于是想到将每个节点的random相对于头节点的偏移量找出来,在新的链表中对应的偏移量找到random节点,指向即可。 起初以为这样做会超时,但结果还好,时间54%,内存60%。 不好的一点是用了很多指针表示位置,有些乱,思路简单是要付出代价的呵呵呵呵。 给出代码: /* // Defin原创 2020-10-04 16:32:38 · 104 阅读 · 0 评论