剑指offer
yyyyeahhhhhh
腾讯测试开发工程师
展开
-
重建二叉树
重建二叉树题目描述解题思路我们用一个栈和一个指针辅助进行二叉树的构造。初始时栈中存放了根节点(前序遍历的第一个节点),指针指向中序遍历的第一个节点我们依次枚举前序遍历中除了第一个节点以外的每个节点。如果 index 恰好指向栈顶节点,那么我们不断地弹出栈顶节点并向右移index,并将当前节点作为最后一个弹出的节点的右儿子;如果 index 和栈顶节点不同,我们将当前节点作为栈顶节点的左儿子;无论是哪一种情况,我们最后都将当前的节点入栈。/** * Definition for a bin原创 2021-03-26 20:05:01 · 127 阅读 · 0 评论 -
复杂链表的复制
复杂链表的复制题目描述:解题思路:原创 2021-02-08 17:49:15 · 138 阅读 · 0 评论 -
调整数组顺序使奇数位位于偶数位前面
题目描述原创 2020-11-14 22:04:27 · 301 阅读 · 0 评论 -
数值的整数次方
数值的整数次方题目描述:在C语言的函数库里面其实有一个pow函数可以用来求一个数值的整数次方,本题的要求其实就是类似的去实现函数pow的功能,要求实现特定的库函数题目解析:由于不需要考虑很大的数字的问题,所以这道题看起来就非常的简单了,但是写出如下的代码就是会出错的代码double Power(double base,int exponent){ int result=1.0; for(int i=1;i<=exponent;i++) { result*=base;原创 2020-10-20 13:19:12 · 297 阅读 · 0 评论 -
用栈模拟实现队列和用队列模拟实现栈
用栈模拟实现队列和用队列模拟实现栈用栈模拟实现队列题目描述从题目的声明中可以看出,一个队列包含了两个栈,stack1和stack2,所以说,这道题目的意图其实是让我们操作两个先进后出的栈实现一个先进先出的队列我们可以通过举例子来分析往队列中插入和删除元素的过程,首先插入一个元素a,把它插入到第一个栈里面,此时第一个栈里面的元素有一个a,第二栈是空的,然后我们再继续压入两个元素b和c元素,依旧是插入到第一个栈里面,那么,现在第一个栈里面就有元素a,b,c了,其中c位于栈顶,此时,第二个栈仍然是空的,原创 2020-10-20 12:52:11 · 447 阅读 · 0 评论 -
丑数
题目描述:解题思路:解题目思路一: 动态规划丑数的递推性质: 丑数只包含因子 2, 3, 5,因此有 “丑数 == 某较小丑数× 某因子” (例如:10 = 5×2)。文字描述:根据丑数的定义,丑数应该是由另一个丑数乘以2或者3或者5得到的结果(1除外),因此,我们就可以去创建一个数组,里面的数字是排好序的丑数,每个丑数都是前面的丑数乘以2或者3或者5得到的结果这种思路的官见在于则囊确保数组里面的丑数是排好序的丑数,并把已有的最大丑数记作M,接下来分析如何产生下一个丑数,该丑数肯原创 2020-09-26 21:11:36 · 353 阅读 · 0 评论 -
翻转单词序列
翻转单词序列题目描述:解题思路:解题思路可以是,先将整个句子进行翻转,然后在翻转每一个单词的内部序列,可以使用逆置的方法,先将整个句子来进行逆置,然后使用同样类似的方法对句子中的单词进行逆置的方法代码如下所示:代码一:class Solution {public: string ReverseSentence(string str) { int len=str.length(); if(len==0) return原创 2020-09-22 17:41:01 · 331 阅读 · 0 评论 -
斐波那契数列
斐波那契数列题目描述:解题思路:斐波那契数列的解题思路,就是一个递归的过程,但是利用递归进行求解的话,时间复杂度会很大,所以如果我们希望降低算法的时间复杂度的话,我们可以将递归形式的算法转化为循环的形式进行求解代码如下:class Solution {public: int Fibonacci(int n) { long long a=1; long long b=1; long long c=1; if(n=原创 2020-07-31 15:29:07 · 196 阅读 · 0 评论 -
数组中只出现一次的数字
数组中只出现一次的数字题目描述解题思路:如果说两个数字不是那么好处理的话,可以先想象一下,如果数组中只有一个数字只出现了一次,其他的数字都出现了两次,那么这个问题怎么解决?可以想到异或运算有一个性质,任何一个数字异或他自己的结果都是0,也就是说,如果我们从头到尾依次异或数组中的每个数字,那么最终的结果就是那个数组中只出现了一次的数字,因为那些承兑出现的两个数字再异或的过程中全部都抵消了。那么现在对两个数字同样进行相同的思考思路,可以尝试着把原先的数组分成两个子数组,使得每个子数组中包含一个只出原创 2020-07-13 13:27:13 · 267 阅读 · 0 评论 -
环的入口结点
环的入口结点题目描述:解题思路:代码如下所示:/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode *detectCycle(ListNode *head)原创 2020-07-01 20:08:31 · 237 阅读 · 0 评论 -
反转单链表(链表逆置)三种思路
链表逆置思路一:例题原创 2020-04-07 15:52:30 · 1874 阅读 · 0 评论 -
股票的最大利润
股票的最大利润题目描述:解题思路股票交易的利润来自股票买入和卖的价格差,当然,我们只能在股票买入了之后再将其卖出。如果把股票买入的价格和卖出的价格的两个数字组成一个数对,那么利润就是这个数对的值,最大的利润,就是这个数对的最大值这个题,当然可以利用暴力法来进行解决,也就是找出数组中所有的数对,并且逐一求出他们之间的差值,由于长度为n的数组中存在有n^2个数对,因此该算法的时间复杂度为n方,当然,也可以换另一种思路先定义一个函数为当卖出价为数组中第i个数字时可能获得的最大利润,显然,再卖出价固定原创 2020-07-08 14:13:09 · 228 阅读 · 0 评论 -
剪绳子
剪绳子题目描述:解题思路:思路一:贪心策略:代码如下所示:class Solution {public: int cuttingRope(int n) { if (n < 4) return n - 1; int a = n / 3, b = n % 3; if (b == 0)return a = pow(3, a); if (b == 1)return a = pow(3, a原创 2020-07-02 15:07:25 · 181 阅读 · 0 评论 -
不用加减乘除做加法
不用加减乘除做加法题目描述:解题思路:针对十进制(1)先理解一下10进制是如何做加法的。例如5+7=12,分为3步。(2)先不考虑进位值,5+7得到2,再计算进位值,个位上5+7的进位为1,所以进位为1*10=10 (要乘以10是因为个位上进一相当于加10).重复(1),(2),直到没有进位制产生,就结束了。例如本题就是再次计算2+10,不考虑进位为12,计算进位得到0,所以最终结果为22对于10进制,还是用到了加法和乘法运算。针对二进制对于2进制的计算也是一样的,由于二进制的特殊原创 2020-06-30 15:30:12 · 945 阅读 · 0 评论 -
数组中出现次数超过一半的数字
数组中出现次数超过一半的数字题目描述:解题思路:思路一:中位数原理现在的情况是,数组中有一个元素的出现次数超过了数组长度的一半,那么我们就可以想到了,如果把这个数组排序的话,那么排序之后的数组,位于数组中央的位置的那个元素一定是那个出现次数超过数组长度一半的元素,也就是说,这个数字是统计学上中位数,即长度为n的数组中第n/2大的元素,所以我们的想法就是先对数组中的元素进行排序,然后返回排好序的数组中第n/2位置上的元素就可以了,就找到了那个元素代码如下:class Solution {p原创 2020-06-23 14:31:46 · 236 阅读 · 0 评论 -
两个链表的第一个公共结点
两个链表的第一个公共结点题目描述:解题思路:思路一:解决这个问题,可以分别把两个链表放在栈里面,这样两个链表的尾巴结点就可以很好得得到了,因为当把两个链表的结点入栈的时候,那么两个链表的尾结点就是当两个栈的栈顶元素,然后接下来只需要去比较两个栈的栈顶元素时候相同,如果两个栈的栈顶元素不相同的话,那么两个链表一定是不相交的,因为如果两个链表是相交的话,那么相交结点之后的所有结点都是相同的,所以相交的两个链表的尾结点一定是相同的。如果两个栈的栈顶元素是相同的的话,那么就需要向后去继续比较,知道不相原创 2020-06-18 20:08:02 · 359 阅读 · 0 评论 -
反转字符串&&反转字符串中单词的序列
反转字符串题目描述解题思路:思路一:直接利用reverse方法逆置数组就可以了class Solution {public: void reverseString(vector<char>& s) { reverse(s.begin(),s.end()); }};思路二:利用交换的思路class Solution {public: void reverseString(vector<char>&原创 2020-06-18 14:36:21 · 183 阅读 · 0 评论 -
合并两个链表
合并两个链表题目描述:思路一:迭代我们可以用迭代的方法来实现上述算法。当 l1 和 l2 都不是空链表时,判断 l1 和 l2 哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位首先,我们设定一个哨兵节点 prehead ,这可以在最后让我们比较容易地返回合并后的链表。我们维护一个 prev 指针,我们需要做的是调整它的 next 指针。然后,我们重复以下过程,直到 l1 或者 l2 指向了 null :如果 l1 当前节点的值小于原创 2020-05-12 16:43:16 · 3574 阅读 · 0 评论 -
删除链表中所有重复的结点
删除链表中所有重复的结点题目描述解题思路:对于删除类的问题需要特别注意的一个点就是链表的头节点,头节点也可能是被删除的结点,所以一般在这种删除类的问题里面,我们都会给出一个伪头结点,为了防止传递二级职责和你这种麻烦的情况出现,首先需要建立一个伪头结点。接下来,就需要我们去遍历整个链表了,如果说当前节点的值与他的下一个结点的值相等的话,那么他们两个就是都需要被删除的了,为了保证删除之后的链表仍然是相互连接在一起的,我们需要把当前结点的前一个结点和后面值比当前结点大的结点进行项链接,我们要确保当前节原创 2020-06-15 17:06:10 · 1076 阅读 · 0 评论 -
链表的倒数第k个结点
链表的倒数第k个结点题目描述:思路一:为了能够只遍历一次就能找到倒数第k个节点,可以定义两个指针:第一个指针从链表的头指针开始遍历向前走k,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历;由于两个指针的距离保持在k,当第一个(也就是快的指针)走到空的时候,第二个指针(走在后面的)指针正好是倒数第k个结点。代码如下:/** * Definition ...原创 2020-05-08 16:13:26 · 158 阅读 · 0 评论 -
从尾到头打印单链表(四种思路)
思路一:这个算法的时间复杂度为O(N^2),空间复杂度为O(1)思路二:这个算法的时间复杂度为O(N),空间复杂度为O(N)思路三:递归如果想用递归来求解问题,首先要看这个问题能否利用递归来求解,也就是说看这个问题能否转换成它的子问题来求解,并且子问题要和原问题具有相同的解法,同时递归问题必须要有递归的出口...原创 2020-04-05 17:11:59 · 1358 阅读 · 0 评论 -
替换空格
替换空格题目描述请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。解题思路看到这个题目之后,我们首先会想到原来的空格是一个字符,替换之后变成了3个字符,那么替换完成之后的字符串的长度是一定会变长的,如果在原来的字符串上进行替换的话,那么就会覆盖修改在该字符串后面的内容。如果是创建新的字符串并且在新的字符串上进行替换,那么我们可以字机分配足够多的内存。这是两种不同的解决方案因为从前向后原创 2020-05-25 17:22:30 · 222 阅读 · 0 评论 -
二维数组中的查找
二维数组中的查找题目描述:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。解题思路一:首先选取数组中右上角数字,如果这个数字等于我们所要查找的数字,那么久结束查找的过程,如果说这个数字大于要查找的数字,那么就删除这个数字所在的这一行,如果这个数字小于我们所要查找的数字,那么我们就删除这个数字所在的行,也就是是说,我们每一次的比较都可以剔除一行或者一列的原创 2020-05-21 16:10:14 · 288 阅读 · 2 评论 -
数组中重复的数字
数组中重复的数字题目描述:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。解题思路:思路一:解决这个问题的一个简单的方法就是先对输入的数组进行排序,从排好序的数组中找...原创 2020-04-27 17:06:06 · 587 阅读 · 0 评论