剑指offer
sifanchao
这个作者很懒,什么都没留下…
展开
-
数组中重复的数字
题目:找出数组中重复的数字 在一个长度为n的数组里的所有数字都在1~n-1的范围内。数字中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。 请找出数组中任意一个重复的数字。例如,如果输入长度为78的数组{1, 2, 3, 5, 3, 1, 4, 0 },那么对应的输出是重复的数字是1和3。方法1: 先将输入的数组排序,其次从头到尾扫描排序后的数组。这里排序一个长...原创 2018-05-29 02:36:48 · 129 阅读 · 0 评论 -
矩阵中的路径
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 下面 这样的3 X 4 矩阵中包含一条字符串”bfce”的路径,但是矩阵中不包含”abfb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路...原创 2018-09-04 16:23:12 · 208 阅读 · 0 评论 -
机器人的运动范围
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?首先,这个方格可以看成是一个m*n的矩阵。同样,在这...原创 2018-09-05 08:56:22 · 362 阅读 · 0 评论 -
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null
此问题包含两个步骤:(1)判断链表中是否有环(2)找出环一、选择快慢指针,让快指针每次走两步,慢指针每次走一步,若是单链表中有环的话,那么两个指针会相遇,此时可返回其在环中的相遇点。二、1)当相遇的时候,设慢指针在环中走了k步,设环之外的部分长为x,环的长度为c,则快指针一共走了 x+m1*c+k步,(m1为快指针在环中走的圈数),慢指针一共走了x+m2*c+k(m2为快指...原创 2018-09-02 11:54:26 · 1524 阅读 · 0 评论 -
减绳子
给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]k[1]…*k[m]可能的最大乘积是多少?例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3的三段,此时得到的最大乘积是18。动态规划首先定义函数f(n)为把长度为n的绳子剪成若干段后各段长度乘积的最大值。在剪第一刀时,我们有n-...原创 2018-09-05 11:35:06 · 747 阅读 · 1 评论 -
二进制中1的个数
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。例如,把9表示成二进制是1001,有2位为1。因此,如果输入9,则该函数输出2。class Solution {public: int NumberOf1(int n) { int count=0; while(n){ if(n&1...原创 2018-09-05 12:16:31 · 134 阅读 · 0 评论 -
数值的整数次方
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。不能使用库函数,同时不需要考虑大数问题。class Solution {public: double Power(double base, int exponent) { double result=1.0; for(int i=1;i&l...原创 2018-09-05 14:39:34 · 105 阅读 · 0 评论 -
打印从1到最大的n位数
输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数999。void Print1ToMaxofNDigits(int n){ int number=1; while(n--) number*=10; for(int i=1;i<number;++i) printf("%d\t"...原创 2018-09-05 16:28:34 · 1189 阅读 · 0 评论 -
删除链表的节点
给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。//假设前提:要删除的节点的确在链表中//时间复杂度:[(n-1)*O(1)+O(N)]/n,结果还是O(1)/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), nex...原创 2018-09-05 17:39:46 · 180 阅读 · 0 评论 -
从尾到头打印链表
思路:栈的思想。遍历链表时每经过一个节点,就把该节点放到栈中。当遍历完整个链表的时候,再从栈中逐个输出节点的值,此时的节点的顺序已经反转过来了。/*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) :* val(x),...原创 2018-09-04 02:04:47 · 94 阅读 · 0 评论 -
旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。采用二分法解答这个问题,mid = low + (high - low)/2 需要考虑三种情况: (1)array[...原创 2018-09-04 14:50:17 · 86 阅读 · 0 评论 -
对一个公司所有员工的年龄排序,要求时间复杂度O(N)
void SortAges(int ages[], int size){ if (ages == NULL || size <= 0) return; const int OldestAge = 99;//定义最大年龄为99岁 int timesOfAge[OldestAge + 1]; for (int i = 0; i <= Ol...原创 2018-09-04 12:26:34 · 630 阅读 · 0 评论 -
青蛙跳台阶问题
一只青蛙一次可以跳1级台阶,也可以跳两级台阶。求该青蛙跳上一个n级台阶总共有多少种跳法。思路:首先考虑n等于0、1、2时的特殊情况,f(0) = 0 f(1) = 1 f(2) = 2其次,当n=3时,青蛙的第一跳有两种情况:跳1级台阶或者跳两级台阶假如跳一级,那么 剩下的两级台阶就是f(2);假如跳两级,那么剩下的一级台阶就是f(1),因此f(3)=f(2)+f(1)...原创 2018-09-04 11:42:43 · 232 阅读 · 0 评论 -
不修改数组找出重复的数字
在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。方法1: 创建一个长度为n+1的辅助数组,然后逐一把原数组的每个数字复制到辅助数组。如果原数组中被复制的数字是m,则把它复制到辅助数组中下标为m的位置。这样就很容易发现哪个数字是重复的。但是这种方法需要创建一个数组,该方案需要O(n)的辅助区...原创 2018-06-14 00:29:10 · 156 阅读 · 0 评论 -
二维数组中的查找
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。思路: 选取右上角的数字。如果该数等于所要查找的数字,则查找过程结束;如果该数字大于要查找的数字,则列数-1;如果该数字小于要查找的数字,则行数+1。 也就是说,如果要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔...原创 2018-06-14 13:51:58 · 106 阅读 · 0 评论 -
替换空格
请实现一个函数,把字符串的每个空格替换成“%20”。例如,输入“We are happy.”,则输出“We%20are%20happy”。思路: 我们首先能够相到的是原来一个空格字符,替换之后变成‘%’、‘2’、‘0’这三个字符,因此字符串会变长。如果是在原来的字符串上进行替换,就有可能覆盖修改在该字符串后面的内存。如果是创建新的字符串并在新的字符串上进行替换,那么我们可以自己分配足够多的内...原创 2018-06-15 11:01:25 · 92 阅读 · 0 评论 -
排序两个数组
有两个排序的数组A1和A2,内存在A1的末尾有容纳足够多的空余空间A2。 请实现一个函数,把A2中的所有数字插入A1中,并且所有的数字是排序的。思路: 从尾到头比较A1和A2中的数字,并把较大的数字复制到A1中合适的位置。这样就能够减少移动的次数,从而提高效率。#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#inc...原创 2018-06-15 13:57:46 · 1904 阅读 · 0 评论 -
重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回分析熟悉二叉树前序&中序遍历规则 前序遍历规则:遍历根节点—->遍历根节点的左子树—->遍历根节点的右子树 中序遍历规则:遍历...原创 2018-09-04 09:08:53 · 107 阅读 · 0 评论 -
二叉树的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。如果节点存在右子树那么它的下一个节点就是它的右子树中的最左子节点。也就是说,从右子节点出发一直沿着指向左子节点的指针,就能找到它的下一个节点。如:节点d 下一个节点是h。节点没有右子树如果节点是它父节点的左子节点,那么它的下一个节点就是它...原创 2018-09-04 10:02:56 · 205 阅读 · 0 评论 -
用两个栈实现一个队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。思路: 创建两个栈s1、s2,其中一个栈(s1)只管压栈数据,另一个栈(s2)出数据。所以问题就好解决了!需要考虑的就是什么时候从s2出栈。两种情况: 1.当s2为空栈时,需要将s1的数据全部倒过来,然后出栈s2。 2.当s2不为空栈时,直接从s2出栈。 最后从s2出的数据就是满足后进先出(队列...原创 2018-09-04 10:32:16 · 148 阅读 · 0 评论 -
用两个队列实现一个栈
思路: 创建两个队列q1、q2,放数据的时候只给当前空队列放数据。 拿出数据时,从当前有数据的队列不断往空队列里压数据,直到剩余一个元素时,这是弹出的数据就是所要数据,满足后进先出的原则。template <typename T>class CStack{public: CStack(void) {} ~CStack(void) {} ...原创 2018-09-04 10:49:52 · 138 阅读 · 0 评论 -
斐波那契数列
方法1:直接递归long long Fibonacci(unsigned i){ if(i<=0) return 0; if(i==1) return 1; return Fibonacci(i-1)+Fibonacci(i-2);}上述方法有很严重的效率问题。计算的节点数会随着i的增大而急剧增加,这意味着计算量会随...原创 2018-09-04 11:13:08 · 224 阅读 · 0 评论 -
字符串的旋转
用 “[ ]”按特定位置访问逐字符拷贝class StringRotation {public: string rotateString(string A, int n, int p) { int i,j=0; string B; for(i=p+1;i<n;i++){ B[j++]=A[i]; ...原创 2018-09-07 12:13:07 · 275 阅读 · 0 评论