
算法
csxcoder
To be or not to be !
展开
-
不用新的变量,交换两个变量的值。
不用新的变量,交换两个变量的值。比如有2个变量a , b ,我们希望交换他们的值。下面介绍两种不同的解法:第一种:基于加减法a = a + b ; //先让a等于和b = a - b ; //和减去原来b的值得到原来a的值,赋值给ba = a - b ; //和减去改变后b的值(原来a的值)得到原来b的值,赋值给a 第二种:基于异或运算a = a ^ b //原创 2015-03-23 10:05:30 · 385 阅读 · 0 评论 -
复杂链表的复制
实现一个函数复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。1 //结点定义2 struct ComplexListNode 3 {4 int m_nValue;5 ComplexListNode* m_pNext;6原创 2015-03-23 10:03:41 · 378 阅读 · 0 评论 -
打印二叉树中和为某一值的路径
输入一个二叉树,查找该树的所有路径(从根结点到叶结点的通路),并返回和(路径上所有结点值的和)为某一指定值的路径。 1 /////////////二叉树中和为某一值的路径///////////////////// 2 void FindPath(BinaryTreeNode* pRoot ,int expectedSum ,vectorint>& path ,int currentSu原创 2015-03-23 10:03:34 · 299 阅读 · 0 评论 -
顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:输入矩阵{1, 2, 3, 4 } {5, 6, 7, 8 } {9, 10, 11, 12 } {13, 14, 15, 16 }输出:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 代码如下:原创 2015-03-23 10:03:15 · 262 阅读 · 0 评论 -
二叉树的镜像
完成一个函数,输入一个二叉树,该函数输出它的镜像 1 void Mirror(BinaryTreeNode* pHead) 2 { 3 if ( pHead == NULL || ( pHead->m_pLeft == NULL && pHead->m_pRight == NULL )) 4 { 5 return; 6 }原创 2015-03-23 10:03:08 · 382 阅读 · 0 评论 -
树的子结构
输入2棵二叉树A和B,判断B是不是A的子结构。1 struct BinaryTreeNode //节点2 {3 int m_nValue;4 BinaryTreeNode* m_pLeft;5 BinaryTreeNode* m_pRight;6 }; 1 bool DoseTree1HaveTree2(BinaryTreeNode*原创 2015-03-23 10:02:57 · 220 阅读 · 0 评论 -
合并两个排序的链表(递归算法)
输入两个递增排序的链表,合并这两个链表并使新链表中的结构任然递增! 1 ///////////////////合并两个排序的链表(递归算法)///////////////////////////////// 2 ListNode* Merge(ListNode* pHead1 ,ListNode* pHead2) 3 { 4 if (pHead1==NULL) 5原创 2015-03-23 10:02:48 · 427 阅读 · 0 评论 -
寻找链表中倒数第K个结点的位置
输入一个链表,输出该链表中倒数第K个结点。 1 struct ListNode 2 { 3 int m_nValue; 4 ListNode* m_pNext; 5 }; 6 ListNode* FindKthToTail(ListNode* pListHead , unsigned int K) 7 { 8 if (!pListH原创 2015-03-23 10:02:34 · 494 阅读 · 0 评论 -
调整数组循序使奇数位于偶数前面
1 void ReorderOddEven(int *pData , unsigned int length) 2 { 3 if (!pData || length 0) 4 { 5 return; 6 } 7 int* pBegin = pData ; 8 int* pEnd = pData + length -原创 2015-03-23 10:02:32 · 381 阅读 · 0 评论 -
在O(1)时间删除链表结点
//给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。 1 struct ListNode //结点结构 2 { 3 int m_nValue; 4 ListNode* m_pNext; 5 }; 6 7 void DeleteNode(ListNode** pListHead , ListNode* pToBeDeleted) 8原创 2015-03-23 10:02:26 · 234 阅读 · 0 评论 -
求一棵普通树的两个结点的最低公共祖先
一棵普通树,树中的结点没有指向父节点的指针,求一棵普通树的两个结点的最低公共祖先。代码如下,我太懒没有加注释,大家自己看吧! 1 #include 2 #include 3 #include 4 using namespace std; 5 6 struct TreeNode //节点 7 { 8 char m_nValue;原创 2015-03-23 10:05:46 · 389 阅读 · 0 评论 -
字符串转换为整数
没有啥好解释的啦,关键是要考虑所有的情况,比如正负号,溢出,输入等。 1 enum Status {kValid = 0 , kInvalid}; 2 bool g_nStatus = kValid ; 3 4 int StrToInt(const char* str) 5 { 6 g_nStatus = kInvalid; 7 long long原创 2015-03-23 10:05:39 · 222 阅读 · 0 评论 -
数组中只出现一次的数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1).例如:输入{2,7,3,10,3,2,5,5} , 输出 7 和 10 。大家首先想到的是顺序扫描法,但是这种方法的时间复杂度是O(n2)。接着大家又会考虑用哈希表的方法,但是空间复杂度不是O(1)。应该怎么做才能即满足时间复杂度是O(n)又满足空间复杂原创 2015-03-23 10:05:02 · 295 阅读 · 0 评论 -
从上往下打印二叉树
要求:从上往下打印二叉树的每个结点,同一层的结点按照从左到右的顺序打印。算法思想:每一次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到一个队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复前面的打印操作,直到队列中所有的结点都被打印出来为止。1 struct BinaryTreeNode //节点2 {3 int m_nValue;4原创 2015-03-23 10:03:27 · 301 阅读 · 0 评论 -
合并两个排序的链表(非递归)
输入两个递增排序的链表,合并这两个链表并使新链表中的结构任然递增!1 struct ListNode 2 {3 int m_nValue;4 ListNode* m_pNext;5 }; 1 ListNode* CreatList(int* data , unsigned int length) 2 { 3 if (!data |原创 2015-03-23 10:02:45 · 423 阅读 · 0 评论 -
将一棵二叉树转换为双向链表的俩中算法
要求:输入一棵二叉排序树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整树中结点的指针的指向。如下图:方法一:我们借助一个容器来顺序存储结点的指针,然后改变指针的指向。 1 //////////////////////二叉搜索树与双向链表(方法一)////////////////////////////////////////// 2 3 void原创 2015-03-23 10:03:51 · 566 阅读 · 0 评论 -
八皇后问题
8个皇后的任意两个不能处在同一行,那么肯定是每一个皇后占一行。于是我们可以定义一个string字符串,字符串中第i个数字表示位于第i行的皇后的列号。先把string字符串分别用0~7初始化,接下来就是对字符串做全排列。因为我们用不同的数字初始化字符串,所以任意两个皇后肯定不同列。我们只需判断每一个排列对应的8个皇后是不是在同一对角线上,也就是对于string的两个下标i和j,是不是原创 2015-03-23 10:03:55 · 239 阅读 · 0 评论 -
数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入数组:{1,3,3,2,3,2,3,3,2}。由于2在数组中出现了5次,超过数组长度的一半,因此要输出2。有两种解法:第一种方法是基于快速排序算法的原理,边排序边判断是否符合输出条件。这种方法的代码我因为没有保存,在电脑蓝屏之后全部消失了·······~~~~(>_第二种方法是根据数组特点找出的算法,时间复杂度为原创 2015-03-23 10:04:00 · 314 阅读 · 0 评论 -
不用加减乘除做加法
写一个函数,求俩个整数之和,要求函数体内不得使用+、-、*、/ 四则运算符合。看到题目,我们知道,现在只有位运算可以用了,那就用位运算吧。第一步:对2个数的每一位相加,但不进位,我们可以用异或运算完成。第二步:找到进位的位置,并计算进位的值,我们先用与运算可以找到位置,然后左移一位,得到进位的值(比如:001 + 101 进位发生在最低位,进位值为 010)第三步:第一步的值和第原创 2015-03-23 10:05:28 · 262 阅读 · 0 评论 -
n个骰子的点数
把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s。输入n,打印出s的所有可能的值和出现的概率。解法二:基于循环求骰子点数,比递归算法更加高端大气上档次具体代码如下,有详细注释。 1 ////////////////基于循环求骰子点数////////////////////////////////////////////////////////// 2 int g_MaxVa原创 2015-03-23 10:05:18 · 328 阅读 · 0 评论 -
和为S的两个数字
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。菜鸟的写法是顺序扫描,时间复杂度是O(n2)。下面给出一种大牛的写法,时间复杂度只需O(n)。 1 //////////////////////和为S的两个数字////////////////////////////////// 2 3 bool Find原创 2015-03-23 10:05:04 · 230 阅读 · 0 评论 -
判断一棵二叉树是不是平衡二叉树
二叉树中任意左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。两种解法。第一种:菜鸟的解法,出现重复遍历,时间复杂度高。 1 bool IsBalanced(BinaryTreeNode* root) 2 { 3 if (root == NULL) 4 { 5 return true ; 6 } 7 int原创 2015-03-23 10:04:57 · 363 阅读 · 0 评论 -
二叉树的深度
多的不解释了,这里有两种解法。第一种:一般的解法 1 void Deep(BinaryTreeNode* root , int& Maxdeep , int count) 2 { 3 if (root->m_pLeft || root->m_pRight) 4 { 5 count++; 6 if (root->m_pL原创 2015-03-23 10:04:55 · 278 阅读 · 0 评论 -
数字在排序数组中出现的次数
统计一个数字在排序数组中出现的次数。例如输入{2,2,2,2,2,3,5,5}和数字2,输出5.常规的顺序扫描法时间复杂度是O(n),可以进一步优化。用二分查找的方法进行查找可以把时间复杂度降为O(logn)。代码如下: 1 int GetFirstK(int* data, int length, int k, int start, int end)//用二分查找法找到第一个K的位原创 2015-03-23 10:04:50 · 230 阅读 · 0 评论 -
两个链表的公共结点
输入两个链表,找出他们的第一个公共结点。链表结点定义如下:1 struct ListNode 2 {3 int m_nValue;4 ListNode* m_pNext;5 }思想:我们可以先遍历一次得到分别得到两个链表的长度,然后计算得出长度差n,那么让较长的链表先走n步,然后两个链表一起向后走,直到两个指针指向同一个结点。这个结点就是我们原创 2015-03-23 10:04:45 · 250 阅读 · 0 评论 -
数组中的逆序对
在数组中的两个数如果前面一个数大于后面的数字,则这俩个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如:数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6)(7,5)(7,4)(6,4)(5,4)。有两种方法:第一种:顺序扫描法,时间复杂度是O(n2)。代码略。第二种:运用归并排序的方法。思想是:把数组递归的分成子数组,统计出相邻子数组的逆序对,统原创 2015-03-23 10:04:43 · 320 阅读 · 0 评论 -
第一个只出现一次的字符
在字符串中找出第一个只出现一次的字符。如输入:“aabcdc”,则输出b 。思路:我们可以把数组当做一个简单的哈希表来用,把每个字母的ASCII码值作为在数组中的位置(下标),数组中存储的是该字符出现的次数。这样我们就创建了一个以字符ASCII码为健值的哈希表。具体代码如下: 1 char FirstNotRepeatingChar(char* pstr) 2 { 3原创 2015-03-23 10:04:35 · 239 阅读 · 0 评论 -
丑数
只包含因子2,3,5的数称作丑数。要求按从小到大的顺序输出指定数量的丑数。有2中方法:第一种:用穷举法,从最小的1开始判断穷举,是丑数就输出,否则继续循环判断。判断的方法是:如果一个数能被2整除,我们把他连续除以2;如果能被3整除,我们把他连续除以3;如果能被5整除,我们把他连续除以5。如果最后得到的值为1,那么这个数就是丑数。具体代码如下: 1 ////////////丑数///原创 2015-03-23 10:04:30 · 261 阅读 · 0 评论 -
把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数子中的最小的一个。例如:输入数组{3,32,121},则打印出 121323 。我们先把数组中的整数转换成字符串,在函数compare中定义比较规则,并根据该规则用库函数qsort排列。最后把排序好的数组中的数字依次打印出来,就是该数组中数字拼接出来的最小数字。这种思路的时间复杂度是O(nlogn)。代码如下:原创 2015-03-23 10:04:21 · 267 阅读 · 0 评论 -
qsort 函数用法
用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *)); 各参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向比较函数的指针 : 注意这里的比较函数必须是返回int型,且2个形参都是 const void * 类型原创 2015-03-23 10:04:18 · 219 阅读 · 0 评论 -
从1到n整数中1出现的次数
输入一个整数n,求从1到n这n个数的十进制表示中1出现的次数。例如:输入12,从1到12这些整数中包含1的数字有1,10,11(这里出现了2次)和12, 一共出现了5次。有2种解法:第一种:穷举法,从1到n,每个数判断一次,判断的方法是每位除以10,若余数为1,这说明改位含1。复杂度为O(n*logn)。代码如下: 1 int NumberOf1(unsigned int n)原创 2015-03-23 10:04:13 · 244 阅读 · 0 评论 -
最小的K个数
输入n个数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8 这8个数,则最小的4个数是1,2,3,4.解法一:O(n)的算法,只有当我们可以修改输入数组时可用 1 int Partitoin(int* input, int low, int high) 2 { 3 if (input == NULL || low 0 || high 0 || low >原创 2015-03-23 10:04:05 · 274 阅读 · 0 评论 -
反转链表
输入一个链表的头结点,反转该链表,并输出反转后链表的头结点。1 struct ListNode 2 {3 int m_nValue;4 ListNode* m_pNext;5 }; 1 ListNode* ReverseList(ListNode* pHead) 2 { 3 ListNode* pReverseHead = NUL原创 2015-03-23 10:02:43 · 226 阅读 · 0 评论