- 博客(53)
- 收藏
- 关注
转载 负数的二进制表示
转载自 http://www.cnblogs.com/junsky/archive/2009/08/06/1540727.html在计算机中,负数以其正值的补码形式表达。什么叫补码呢?这得从原码,反码说起。 原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。比如 00000000 00000000 00000000 00000101 是 5的 原码
2015-02-27 22:54:16
426
原创 不用加减乘除做加法
1.问题描述写一个函数,求两个整数之和,要求函数体内不得使用加减乘除运算符。2.分析我们分析做十进制加法时,可以分为三步进行例如 5+17 , 1)各位相加不进位 5+7 = 12 , 2)第二步做进位 5+7有进位 进位的值是10 ,3)把前面两个结果加起来 12+10的结果是22 ,对于二进制同样也遵循这个规律。3.代码int add(int
2015-02-03 20:35:49
537
原创 求1+2+....+n
1.问题描述求1+2+....+n,要求不能使用乘除法,for,while,if,else switch,case等关键字及条件判断语句。(来自《剑指offer》)2.分析在c语言里面我们可以使用函数指针,来调用不同的函数,达到题目的要求。3.代码unsigned int Solution_Teminator(unsigned int n){ retu
2015-02-03 18:21:11
366
原创 圆圈中最后剩下的数字
1.问题描述题目0,1......n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。(来自《剑指offer》)2.分析1)用环形链表模拟圆圈,然后扫描链表删除结点,如果扫描到了链表结尾,重新在指向链表开头以此来模拟环形链表。typedef struct node{ int data;
2015-02-03 13:47:48
373
原创 左旋字符串
1.问题描述字符串的左旋操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果“cdefgab”。2.分析其实和翻转单词顺序差不多,我们可以先将前面2位翻转得到 ba,在将后面5位翻转得到 gfedc ,然后再将整个字符串翻转得到 cdefgab。3.代码
2015-02-03 11:20:46
356
原创 翻转单词顺序
1.问题描述输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字幕一样处理。例如输入字符串 “I am a student.” 则输出"student. a am I".2.分析我们可以第一步翻转句子中所有的字符。比如反转 I am a student中所有的字符得到 ".tneduts a ma I" 第二步在翻转每个单词中字符的顺序得
2015-02-03 10:56:19
373
原创 和为s的连续正数序列
1.问题描述输入一个正数s,打印出所有和为s的连续正数序列(至少有2个数)。例如输入15,有1,2,3,4,5. 4,5,6 7,8。三个序列输出。2.分析我们可以定义2个指针分别指向small和big,然后我们开始求 small和big的和,如果和等于要求的和,那我们打印这个序列并将small向后移动,并从当前的和里面减去当
2015-02-02 21:45:06
416
原创 和为s的两个数字
1.问题描述输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得他们的和正好是s,如果有多对数字的和等于s,输出任意一对即可。2.分析如果首先想到的可能是穷举,但是这样的话就会浪费掉递增排序的这一性质,并且时间复杂度时o(n2) ,因为他是递增的 ,我们可以设置两个指针一个指向头一个指向尾。然后 求和 如果等于的话,就得到了一对答案,如果大于,那我们就向前移动尾指针
2015-02-02 21:10:21
375
原创 数组中只出现一次的数字
1.问题描述一个整型数组里除了俩个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度o(n),空间复杂度o(1);2.分析如果说只有一个数字的话,那我们能想到使用异或运算(两个相同数字异或等于0)这样最后得到的就是那个只出现一次的数字。这里我们假如可以将数组分为两部分,使这俩个只出现一次的数字位于俩个数组中,而其他的数字都成对出现两次,这样就可以得到这
2015-02-02 17:20:04
325
原创 判断二叉树是不是平衡二叉树
1.问题描述输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。2.分析我们可以采用后续遍历,在遍历根结点之前就可以得到左右子树的深度及是不是一颗平衡二叉树。然后在根据左右子树的深度差值来判断这棵树是不是一棵平衡二叉树。3.代码int IsBalanced(TreeNode* head,
2015-02-02 16:19:05
313
原创 二叉树的深度
1.问题描述输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根 叶结点)形成树的一条路径,最长路径的长度求树的深度。2.分析最长路径的长度即为左子树或右子树中相对较长的一棵子树的深度在加1(加上的是当前左子树右子树的父亲)。3.代码int GetTreeLength(TreeNode* node){ if (node =
2015-02-02 15:38:34
305
原创 数字在排序数组中出现的次数
1.问题描述统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3 由于3在这个数组中出现了4次,因此输出4.2.分析因为数组是排序的,我们可以通过这个性质分别找到第一个k和最后一个k,然后计算出k的个数。找k的时候,以前二分查找的时候 找到了k ,我们还要判断是不是第一个k或最后一个k,如果不是的话还要继续查找。直至找到第一个k和最后一
2015-02-02 14:57:34
287
原创 两个链表的第一个公共结点
1.问题描述输入两个链表,找出他们的第一个公共结点。2.问题分析我们可以先统计出2个链表的长度,然后计算两个链表相差的结点数,让长的链表先走相差的结点数,然后俩个链表在一起走,直到遇到相同的结点,然后返回。3.分析ListNode* FindFirstCommonNode(ListNode *head1,ListNode *head2){ if (he
2015-02-02 10:43:14
314
原创 第一个只出现一次的字符
1.问题描述在字符串中找出第一个只出现一次的字符。例如输入abaccdeff,则输出 b。2.分析我们可以用一个容器来存放 对应的字符和出现次数(哈希表 这里仅仅用数组来简单的模拟了一下),第一次扫描时将出现的次数存放在表中,第二次扫描时扫描到次数为1的字符并返回该字符即可。表的大小为256,因为字符是8个bit的类型,总共有256个字符。3.代码char Fi
2015-02-01 22:17:48
309
原创 丑数
1.问题描述我们把只包含因子2,3和5的数称作丑数。求按从小到大顺序的第1500个丑数。例如6,8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做第一个丑数。2.分析我们设置一个数组,这里面保存着排好序的丑数,因为丑数是按顺序存放在数组中的。对乘以2而言,肯定存在某一个丑数T2,排在它之前的每一个丑数乘以2得到的结果都会小于已有的最大的丑数,在它之后的每一个丑数乘以2
2015-02-01 21:14:44
431
原创 连续子数组的最大和
1.问题描述输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为o(n)。2.分析当 当前和为负数时我们在计算最大和时直接从下个值开始,否则的话在当前和加上下个值在与记录的最大值比较,如果比纪录的最大值还大,那更新记录的最大值。3.代码int FindGreatestSumOfArray(i
2015-02-01 19:34:25
285
原创 最小的k个数
1.问题描述输入n个整数,找出其中最小的k个数,例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4.2.分析
2015-02-01 18:53:21
320
原创 数组中出现次数超过一半的数字
1.问题描述数组中有一个数字超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.2.分析1)数组中有一个数字出现的次数超过了数组长度的一半。如果把这个数组排序那么中间的那个数字(中位数)一定是出现次数超过一半的数字,快速排序中的partition函数可以得到数
2015-02-01 12:14:01
337
原创 全排列问题
1.问题描述输入一串数字,打印出该数组中数字的全排列,例如 1 2 3 的全排列包括 123,132,213,231,312,321.2.分析我们可以分成两步 1.把第一个数字和后面的数字交换。2. 固定一个数字求后面数字的全排列。3.代码#include void swap(int *one,int *two){ int temp = *one;
2015-01-28 21:38:57
435
原创 二叉搜索树与双向链表
1.问题描述输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。2.分析对于二叉搜索树我们知道,树的左孩子都比根节点要下,树的右孩子都比根结点要大,根据这个特点,我们进行中序遍历得到的序列就会满足题目的要求,我们另外需要做的就是对结点的指针进行操作,记录一下上次访问的元素,将当前元素的left指针指向上次访问的元素,
2015-01-28 20:20:27
328
原创 二叉树中和为某一值的路径
1.问题描述输入一颗二叉树和一个整数,打印出二叉树中的结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。2.分析找到值为某一值的路径,我们知道无非就是树的遍历,但是怎么保存呢?因为树在遍历的时候需要递归,我们可以用栈来保存路径。比如:我们开始遍历 先是根结点 压栈,在是左孩子 压栈,如果左孩子是叶子结点的话,那么我们判断和是不是我们期望的
2015-01-28 17:50:50
352
原创 二叉搜索树的后序遍历序列
1.问题描述输入一个整数数组,判断该数组是不是某二叉树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。2.分析二叉搜索树有一个性质为:左子树的元素都比根结点要小,右子树的元素都比根结点要大,根据这个性质我们来划分左右子树,在判断右子树是不是都比根结点要大(我们划分时,左子树一定满足条件,因为我们就是按照比根结点小的是左子树来划
2015-01-28 12:41:05
333
原创 从上往下打印二叉树
1.问题描述从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。2.分析我们可以使用队列这个容器,将元素压入队列,打印时每次从队列中取出一个元素打印其值,并且如果该节点有左孩子或右孩子,在将其左孩子右孩子压入队列,直至队列为空。(这个和有向图的广度优先遍历一个思想,树是图的一种特殊退化形式)。3.代码void PrintTreeFromTopTo
2015-01-28 12:02:56
397
原创 栈的压入弹出序列
1.问题描述输入两个整数序列,第一个序列表示栈的压入序列,请判断第二个序列是否为该栈的弹出序列。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压栈序列,序列4,5,3,2,1是该栈序列对应的一个弹出序列,但 4,3,5,1,2,就不可能是该压栈序列的弹出序列。2.分析我们可以用一个辅助栈来协助我们判断,当辅助栈的栈顶元素是要弹出序列中的元素时,我们就对辅助栈进
2015-01-28 10:22:07
328
原创 包含min函数的栈
1.问题描述定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的函数,在该栈中调用min,push及pop的时间复杂度都为o(1).2.分析我们可以使用一个辅助栈,专门来处理题目中得到栈的最小元素的函数时间复杂度为o(1)的这个需求。 当我们压栈时,另外一个栈正常进行,对辅助栈的压栈做法是这样的 假如当前压入的这么元素比top元素要小,那我们压人,如果比顶端元素大,那么我们在把
2015-01-27 20:22:07
332
原创 树的镜像
1.问题描述请完成一个函数,输入一个二叉树,该函数输出它的镜像。2. 分析镜像就是在镜子中看到的景象,比如一棵树8 的镜像为 8 ,只是将左右子树交换。610 10 63.代码#include typedef struct node{ int data; struct
2015-01-27 19:17:37
340
原创 树的子结构
1.问题描述输入两颗二叉树A和B,判断B是不是A的子结构。2.代码#include #include typedef struct node{ int data; struct node* lChild; struct node* rChild; }TreeNode;int Tree1HasTree2(Tr
2015-01-27 13:08:17
299
原创 合并俩个排序的链表
1.问题描述输入俩个递增排序的链表,合并这俩个链表并使新链表中的结点仍然递增有序。2.代码typedef struct node{ struct node* next; int data; }ListNode;ListNode* MerageList(ListNode* one, ListNode* two){ if (one ==
2015-01-27 11:11:41
239
原创 反转链表
1.问题描述定义一个函数,输入一个链表的头结点,反转该链表病输出翻转后链表的头结点。2.分析反转链表需要注意,头指针为空或者整个链表只有一个结点时,反转后链表有没有断裂,反转后头结点是否是原来的尾结点。3.代码typedef struct node{ int data; struct node *next; }ListNode;Lis
2015-01-27 10:44:23
354
原创 链表中倒数第k个结点
1.问题描述输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第一个结点。例如一个链表有6个结点,从头开始它们的值依次是1,2,3,4,5,6。这个链表的倒数第3个结点是值为4的结点。2.分析倒数第k个结点我们可以声明2个指针让第一个指针先走k-1步,那么这俩个指针相隔距离为k。待第一个指针指向链表末尾时,第二个指针即为倒数
2015-01-24 17:48:49
395
原创 调整数组的顺序使奇数位于偶数的前面
1.问题描述输入一个整形数组,实现一个函数来调整该数组中的数字的顺序,使得所有奇数位于数组的前半部分,所有的偶数位于数组的后半部分。2.分析这个问题只需要定义2个指针,一个指向头一个指向尾,头指针向后遍历当指向偶数时,尾指针向前遍历当指向奇数时,交换2个元素的位置。我们可以将这个代码设计的更具扩展性一些(比如题目改为负数在前,正数在后等等),因此我们使用单独的一个函数来判断数字
2015-01-24 16:53:49
374
原创 删除链表的结点
1.问题描述给定链表的头结点和待删除结点,要求删除链表的结点要求时间复杂度为o(1)。2.分析我们都知道链表的要想访问某个结点必须要从头结点挨个遍历,并且单链表我们没有指向前驱的结点,因此我们可以用狸猫换太子(用这个待删除结点的下个结点里面的内容,复制到这个待删除结点,然后删除下个结点),这样就可以用o(1)时间复杂度来完成题目要求。但是如果这个待删除结点为尾结点没有下个结点,
2015-01-24 12:16:09
362
原创 打印1到最大的n位数
1.问题描述输入数字n,按顺序打印出从1刀最大的n位数的十进制数。比如输入3,则打印出1,2,3一直到最大的3位数999.2.分析对于这个问题,我们需要考虑大数。因此我们在字符串上模拟加法运算。3.代码/* nTakeOver代表进位,isNotOverFlow代表有没有溢出(是不是达到了n位的最大数了)。 我们每次对个位进行加一运算,判断是不是该进位,如果
2015-01-24 11:05:48
380
原创 数值的整数次方
1.问题描述实现函数 double Power(double base,int exponent), 求base的exponent次方,不得使用库函数,同时不考虑大数问题。2.分析这个问题需要考虑的一些情况包括,exponent为负数的话,base为0 并且exponent为负数的话。3.代码#include int isNotInvalid = 0
2015-01-24 09:05:24
345
原创 二进制中1的个数
1.问题描述请实现一个函数,输入一个整数,输出该二进制表示中的1的个数,例如输入9,9的二进制表示为1001,输出2。思路1先判断整数二进制最右边是不是1接着把整数右移一位在判断是不是1,这样每次移动一位直到整个整数变为0为止。只要把整数和1做位于运算看结果是不是0就知道了,1除了最右边一位之外所有位都是0。int NumberOfOne(int n){
2015-01-20 15:16:09
336
原创 斐波那契数列
1.问题描述写一个函数输入n,求斐波那契数列的第n项。2.分析递归有严重的效率问题,会多次的求某一个值的结果。long long Fibonacci(unsigned int n){ if (n == 0 || n == 1) { return n; } int one = 0; int two =
2015-01-20 14:43:04
371
原创 旋转数组的最小数字
1. 问题描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出该旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.2.分析首先我们可以看到原数组为递增排序的,并且以最小元素为界左边的为递增有序,右边的也为递增有序因此我们可以使用二分查找。我们定义3个指针left,ri
2015-01-20 14:17:01
317
原创 排序算法之归并排序
归并排序的原理归并排序递归的将待排序数组分为左,右2段,然后分别对左右2段数组在分别排序,直到待排序长度变为1时(长度为1的序列有序),然后开始归并,归并的过程中,按照元素的大小归并到原数组中,最终使原数组有序。贴上一张图便于大家理解。#define INFINITE 1000000 void Merage(int* array, int start,int end,i
2015-01-20 10:45:26
386
原创 排序算法之选择排序
选择排序的原理选择排序是遍历数组找到一个最小的元素然后将其和第一个位置上的元素交换(这样最小元素在第一个位置上最小元素就排好序了),然后接下来从第二个元素开始遍历在找最小,在替换,依此类推。代码void Selected_Sort(int* array,int length){ for (int i = 0; i < length; i++) {
2015-01-19 21:25:20
241
原创 排序算法之冒泡排序
冒泡排序的原理冒泡排序对数组进行遍历的过程中比较前后2个元素的大小,如果前一个元素大于后一个元素,那么交换这俩个元素的位置,遍历结束后最大的元素位于数组的顶端,那么下次遍历的时候,遍历到数组倒数第二个元素(因为最大元素已经在他应该在的位置上了)。第二次遍历完成后第二大的元素 位于数组倒数第二个元素的位置上,依此类推。代码void Bubble_Sort(int *array
2015-01-19 21:03:45
289
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人