![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
剑指offer
文章平均质量分 65
xc889078
这个作者很懒,什么都没留下…
展开
-
约瑟夫环--O(n)算法
转载地址:http://zhedahht.blog.163.com/blog/static/2541117420072250322938/题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。首先定转载 2013-06-20 15:29:52 · 736 阅读 · 0 评论 -
翻转单词顺序
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。分析:两次翻转。#include void reverse(char *begin, char *end)//指针值传递,原调用函数的指针值没有变化{ if(begin == NULL || end == NULL) return; char temp;原创 2013-06-19 21:24:22 · 497 阅读 · 0 评论 -
打印所有和为s的连续正数序列
题目:输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。分析:定义small,big两个整数,当前和值小于s,则加big,大于s,则减去small,直到等于s。#include void print_num(int small, int big){ int i; for(i=small;i<=big;i++) printf("%d\t",i);原创 2013-06-19 20:32:20 · 724 阅读 · 0 评论 -
查找数组中和为s的两个数字
题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。分析:两个指针,一个从数组头部开始向后扫,一个从数组尾部向前扫,如果两个指针指向的数组值的和大于s,则后面的指针向前移,否则前面的指针向后移,直到两个值得和等于s。#include bool find(int a[], int len, int sum, in原创 2013-06-19 20:01:03 · 852 阅读 · 0 评论 -
判断是否是平衡二叉树
题目:输入一颗二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一颗平衡二叉树。分析:后续遍历,从二叉树的叶子节点开始一步一步的向上比较,一旦某个节点不满足平衡二叉树要求,则直接返回false,感觉有点像斐波那契的非递归算法。#include #include typedef struct node{ int val原创 2013-06-19 17:34:05 · 719 阅读 · 0 评论 -
统计数组中的逆序对
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。分析:借鉴归并排序的思想。#include int find_core(int *a, int *b, int start, int end){ if(start == end) return 0; int mid = (start+en原创 2013-06-19 10:29:18 · 685 阅读 · 0 评论 -
寻找丑数
题目:我们把只包含因子2、3和5的数称作丑数。求按照从小到大的顺序的第1500个丑数。#include int Min(int a, int b, int c){ int min = (a<b)?a:b; min = (min<c)?min:c; return min;}int find_ugly(int n){ if(n<=0) return 0; int *pu原创 2013-06-18 21:34:59 · 592 阅读 · 0 评论 -
找出两个链表的第一个公共结点
题目:输入两个链表,找出它们的第一个公共结点。分析:先找出两个链表哪个长,然后让长链表先走几步,之后使两个链表从同一起始地点一起走,互相比较,找到第一个相同结点将其返回。#include #include typedef struct node{ int vlaue; struct node *next;}node,*pnode;void create_原创 2013-06-19 11:32:25 · 588 阅读 · 0 评论 -
删除字符串中所有重复出现的字符
#include void delete_char(char *a){ if(a==NULL) return; char hash_table[256] = {0}; char *p = a; while(*p != '\0') hash_table[*p++]=1;//注意这里,设为1标识这个字符出现过一次,为后面删除重复字符做准备 char *fas原创 2013-06-18 22:21:40 · 1489 阅读 · 0 评论 -
从一个字符串中删除另一个字符串中出现的字符
#include void delete_char(char *a, char *b){ if(a==NULL || b==NULL) return; char hash_table[256] = {0};//创建简单哈希数组,存储字符串b中每个字符出现的次数 char *p = b; while(*p != '\0') hash_table[*p++]++原创 2013-06-18 22:07:09 · 859 阅读 · 0 评论 -
第一个只出现一次的字符
题目:在字符串中找出第一个只出现一次的字符。分析:建立一个简单哈希数组,下标是字符的ASCII值,数组值是字符出现的次数#include char find(const char *str){ if(str==NULL) return '\0'; int hash_table[256] = {0};//创建简单哈希数组,下标是字符的ASCII值,数组值是字符出现的原创 2013-06-18 21:47:41 · 478 阅读 · 0 评论 -
连续子数组的最大和
#include bool isvalid = false;//全局标识位,标识find_max返回的0是0值还是因为输入有误返回的0int find_max(int a[], int len, int *pstart, int *pend){ if(a==NULL || len<=0 || pstart==NULL || pend==NULL) { isvali原创 2013-06-18 17:57:02 · 494 阅读 · 0 评论 -
最小的k个数
题目:输入n个整数,找出其中最小的k个数。思路:利用快排思想,使得比k个数字小的所有数字都位于数组的左边,比k个数字大的所有数字都位于数组的右边。#include #define K 4int partition(int a[], int left, int right){ int i=left,j=right; int temp = a[i]; while原创 2013-06-18 15:44:35 · 482 阅读 · 0 评论 -
统计数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数。分析:利用二分查找分别找到第一次出现该数的位置和最后一次出现该数的位置。#include int get_first(int a[], int len, int k, int start, int end){ if(start > end)//如果没有找到所找数字,返回-1 return -1; int mid = (start+en原创 2013-06-19 16:24:49 · 680 阅读 · 0 评论 -
二叉树的深度
#include #include typedef struct node{ int value; struct node *left; struct node *right;}node,*pnode;void create_tree(pnode *root)//按照前序遍历的顺序输入{ int value; scanf("%d",&value)原创 2013-06-19 17:15:35 · 479 阅读 · 0 评论 -
字符串的左旋转
题目:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。分析:三次旋转。#include void reverse(char *begin, char *end)//指针值传递,原调用函数的指针值没有变化{ if(begin == NULL || end == NULL) return; char temp;原创 2013-06-19 21:37:39 · 526 阅读 · 0 评论 -
二叉树两个结点的最低公共祖先
转载地址: http://blog.csdn.net/ssjhust123/article/details/7938503 http://zhedahht.blog.163.com/blog/static/25411174201081263815813/1. 二叉搜索树 给定一棵二叉搜索树(BST),找出树中两个结点的最低公共祖先结点(转载 2013-06-20 20:52:16 · 1001 阅读 · 0 评论 -
从1到n整数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数中的十进制表示中,1出现的次数。分析:我们用一个稍微大一点的数字21345作为例子来分析。我们把从1到21345的所有数字分成两段,即1-1235和1346-21345。先来看1346-21345中1出现的次数。1的出现分为两种情况:一种情况是1出现在最高位(万位)。从1到21345的数字中,1出现在10000-19999这10000个数字原创 2013-06-21 16:01:54 · 777 阅读 · 0 评论 -
数对之差的最大值
题目:在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。#include int find_diff(int a[], int len)//动态规划,对于减数a[i],它的最大差值就是a[i]之前的最大值减去a[i],遍历一遍数组,找出这些最大值中的最大值,时间复杂度O(n){ if(a==NULL || len < 2)//至少要2个数 retur原创 2013-06-25 11:08:34 · 926 阅读 · 0 评论 -
颠倒栈
题目:用递归颠倒栈。分析:假设栈内从栈顶元素到栈底元素依次为5,4,3,2,1,则可以将其分成两部分:栈顶5和其他元素4,3,2,1,只要吧4,3,2,1颠倒后变为1,2,3,4,再将栈顶元素5插到栈底,则变成1,2,3,4,5,而4,3,2,1的颠倒同理,递归即可解决。#include #include using namespace std;void add_to_bo原创 2013-06-24 17:14:14 · 779 阅读 · 0 评论 -
定义一个函数求字符串的长度,要求该函数体内不能声明任何变量
#include int get_len(char *a){ if(a == NULL) return 0; if(*a == '\0') return 0; return get_len(a+1)+1;}int main(){ char a[] = "abcdefg"; printf("%s长度为%d\n",a,get_len(a));原创 2013-06-24 16:29:53 · 597 阅读 · 0 评论 -
从1到N的二进制形式正数中1出现的次数
例如:f(11) = f(1011) = 20(1,10,11,100,101,110,111,1000,1001,1010,1011)思路:先考虑第一位上的1(第几位一律从右侧数起),第一位上的1是每两个数出现1次,因此可以先计算11/2=5,然后对于11%2=1的部分,由于等于1,因此出现了一次1,故第一位上共出现了6次1;再考虑第二位,这一位上是每4个数出现2次1,先计算11/4*2=4原创 2013-06-21 17:39:30 · 1648 阅读 · 0 评论 -
把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印出能拼接出的所有数字中的最小的一个。分析:考虑到整数拼接起来会超出整数范围,所以涉及大数问题,用字符串处理。两个数字m和n能拼接成mn或者nm,如果mn大于nm,那么n应该放在m前面,反之m放在n前面,多个整数道理一样。#include #include #include #define Max_num_le原创 2013-06-20 22:03:23 · 607 阅读 · 0 评论 -
n个骰子的点数
题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。分析:动态规划,表格法,因为当前表格只与上一个表格有关,所有只需要创建两个数组即可,一个数组存储已经计算好的骰子的和出现的次数,另一个数组存储需要计算的骰子的和出现的次数,这两个数组相互依赖,彼此交换。计算的时候,需要计算次数的数组中和为s的次数等于已经计算好的数组中和为s-1,s-2,s-3,原创 2013-06-20 10:09:07 · 781 阅读 · 0 评论 -
atoi的实现
需要注意的地方:1 需要设置全局变量,用于判断函数返回的0是因为输入错误还是真正需要返回的2 判断字符串地址是不是空3 判断字符串是不是空字符串4 判断字符串有没有正负号5 判断字符串是不是只有正负号6 判断转换后的整数会不会超出整数范围7 判断除第一位正负号(如果有的话)以外有没有不是0~9的字符enum status {valid=0,invalid};//全局原创 2013-06-20 16:33:03 · 544 阅读 · 0 评论 -
判断扑克牌的顺子
题目:从扑克牌中随机抽取5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。分析:将其转换为整数数组,大小王为0,将数组排序,统计数组中的0的个数以及空缺的个数,因为0可以补空缺,空缺是指两个整数差值大于1时的差值,比如2和4之间不连续,空缺1,如果0的个数不小于空缺的个数,说明是顺子,否则不是顺子。#in原创 2013-06-20 11:37:37 · 764 阅读 · 0 评论 -
求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
#include int sum(int i){ (i!=0) && (i=i+sum(i-1)); return i;}int main(){ int a = 5; printf("%d\n",sum(a)); return 0;}原创 2013-04-26 15:46:42 · 698 阅读 · 0 评论 -
判断变位词
题目:在英语中,如果两个单词中出现的字母相同,并且每个字母出现的次数也相同,那么这两个单词互为变位词。请完成一个函数,判断输入的两个字符串是不是互为变位词。#include #include bool is_anagram(char *a, char *b){ if(a==NULL || b==NULL) return false; if(strlen(a)!=strlen(b原创 2013-06-19 09:26:54 · 1566 阅读 · 0 评论 -
最小的k个数--适合处理海量数据
#include #include //multiset所属头文件using namespace std;#define K 4void find_number(int a[], int len, multiset > &set_number, int k){ set_number.clear(); if(a==NULL || len len) retur原创 2013-06-18 16:56:24 · 520 阅读 · 0 评论 -
反转单链表--迭代和递归分别实现
#include #include typedef struct node{ int value; struct node *next;}Listnode;Listnode* CreateList(Listnode *head)//建立链表{ if(head == NULL) return NULL; head = (Listnode*)ma原创 2013-05-15 09:03:26 · 908 阅读 · 0 评论 -
求链表的中间结点
题目:如果链表中节点总数为奇数,返回中间结点,如果结点总数是偶数,返回中间两个结点的任意一个。分析:两个指针,快指针一次走两步,慢指针一次走一步,快指针走到尾部,慢指针即指向链表中间结点。#include #include typedef struct node{ int value; struct node *next;}node,*pnode;void create_原创 2013-06-14 16:47:42 · 750 阅读 · 0 评论 -
二进制相关算法
1、求整数二进制中1的个数解析:把一个整数减1,再和原整数做与运算,会把该整数最右边一个1变成0。那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。#include int numof1(int num){ int count = 0; while(num) { ++count; num = num&(num-1); } retu原创 2013-06-13 15:19:38 · 663 阅读 · 0 评论 -
打印1到最大的n位数
题目:输入数字,按顺序打印出从1到最大的n位十进制数。分析:由于存在大数可能,所以用字符串存储大数。#include #include #include void print_number(char *number)//打印,去掉前面的'0'{ int len = strlen(number); int i; bool isbeginning0 = true; for(i原创 2013-06-13 19:30:47 · 555 阅读 · 0 评论 -
链表中倒数第k个结点
题目:输入一个链表,输出该链表中倒数第k个节点。分析:一个快指针,一个慢指针,快指针和慢指针之间差k-1个节点,快指针到尾部,慢指针指向的节点即是所找节点。#include #include typedef struct node{ int value; struct node *next;}node,*pnode;void create_list(pn原创 2013-06-14 11:25:12 · 465 阅读 · 0 评论 -
在O(1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。分析:找到删除结点的后面的节点,将其内容复制到该删除的节点,然后删除后面这个节点即可。#include #include typedef struct node{ int value; struct node *next;}node,*pnode;void create_list(pnode原创 2013-06-14 10:17:58 · 521 阅读 · 0 评论 -
旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小值元素。解析:因为数组递增排序,所以可以采用二分查找的方法。#include int find_inorder(int a[], int begin, int end)//数组顺序查找最小值{ int i; int min = a[begin];原创 2013-06-13 14:41:41 · 470 阅读 · 0 评论 -
调整数组顺序使偶数位于奇数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于奇数前面。分析:两个指针,一个指针从开头扫描,直到遇到奇数,一个指针从尾部扫描,直到遇到偶数,奇数偶数交换,直到两个指针相遇。#include void tiaozheng(int a[], int len){ if(a==NULL || len<=0) retu原创 2013-06-14 10:41:04 · 582 阅读 · 0 评论 -
数值的整数次方
题目:实现函数double power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。#include bool invalid_input = false;//用于判断返回值是真正地0值还是因为输入有误返回bool equal0(double num)//判断double类型数据是否为0{原创 2013-06-13 16:46:56 · 461 阅读 · 0 评论 -
两个栈实现一个队列
#include #include #include using namespace std;template class CQueue{ public: CQueue(){} ~CQueue(){} void queue_append(T &element); void queue_delete(); private: stack原创 2013-06-13 09:51:41 · 486 阅读 · 0 评论 -
两个队列实现一个栈
解析:保证两个队列有一个队列为空,非空队列用于入队,空队列用于存储非空队列出队的元素,依次交替进行。#include #include #include using namespace std;template class CStack{ public: CStack(){} ~CStack(){} void stack_push(const T& element)原创 2013-06-13 09:33:55 · 455 阅读 · 0 评论