点滴算法
文章平均质量分 91
常见算法和数据结构的C/C++实现,分析算法性能
Sunshine_top
安安静静、认认真真完成自己的事情
展开
-
位运算的常见操作和题目
一、位运算基本操作& 与 1 & 1 = 1;1 & 0 = 0;0 & 0 = 0 只有当两个位都为1时,结果为1| 或 1 | 1 = 1;1 | 0 = 1;0 | 0 = 0 只有两个位都为0时,结果为0^ 异原创 2015-06-29 21:04:09 · 5379 阅读 · 2 评论 -
n个骰子的点数
题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。方法一:递归思路:设n个骰子某次投掷点数和为s的出现次数是F(n, s),那么,F(n, s)等于n - 1个骰子投掷的点数和为s - 1、s - 2、s - 3、s -4、s - 5、s - 6时的次数的总和:F(n , s) = F(n - 1, s - 1) + F(n -原创 2015-06-26 21:21:15 · 2791 阅读 · 0 评论 -
KMP(Knuth-Morris-Pratt)算法
一、朴素匹配算法也就是暴力匹配算法。设匹配字符串的长度为n,模式串的长度为m,在最坏情况下,朴字符串匹配算法运行时间为O((n - m + 1)m)。如果m = n / 2, 那么该算法的复杂度就是Θ(n ^ 2)。由于不需要预处理,朴素字符串匹配算法运行时间即为其匹配时间。strstr()函数就可以用这个方法实现,尽管效率不高://strstr函数char *strStr(co原创 2015-06-25 15:40:08 · 4201 阅读 · 1 评论 -
字符串的排列/组合
字符串“abc”的全排列:abc acbbacbcacbacab例如字符串“abc”的全排列:以a开头的全排列是a{bc},递归得到bc的全排列,而bc的全排列又是以b开头,c的全排列(即c自己); 同样,以b开头的全排列是b{ac},递归得到ac的全排列,而ab的全排列又是以a原创 2015-06-21 16:01:38 · 2148 阅读 · 0 评论 -
栈和队列的相互模拟
队列是先进先出的数据结构,栈时先进后出的数据结构,可以使用栈和队列模拟彼此。两个队列模拟栈使用C++泛型编程,队列使用STL的queue容器适配器。主要思想:两个队列模拟栈时,某时刻要么两个队列均为空,要么有一个队列为空。(1)向栈中push时:如果两个队列均为空,将元素插入某个队列(这里假定插入队列1);原创 2015-06-18 09:43:40 · 2002 阅读 · 0 评论 -
不借助变量交换两个数
交换两个数在排序算法中用的很多:冒泡排序中 、插入排序中等等。正常的交换两个数是借助一个变量tmp:void Swap(int &a, int &b) { int tmp = a; a = b; b = tmp;}在面试题中有这样的题目“不借助第三个变量,交换两个数”//A方法void Swap(int &a, int &b) { a = a + b;b = a - b;原创 2015-03-17 15:36:31 · 2024 阅读 · 0 评论 -
生成k个小于n的互不相同的随机数
《编程珠玑》习题1.4:如果认真考虑了习题3,你将会面对生成小于n且没有重复的k个整数的问题。最简单的方法就是使用前k个正整数。这个极端的数据集合将不会明显的改变位图方法的运行时间,但是可能会歪曲系统排序的运行时间。如何生成位于0至n - 1之间的k个不同的随机顺序的随机整数?尽量使你的程序简短高效。如下的程序产生1-n的不重复的随机数:void swap(int *a, in原创 2015-06-16 16:20:17 · 2662 阅读 · 0 评论 -
位操作实现加减乘除四则运算
常见的位操作实现1. 常用的一个等式:-n = ~(n - 1) = ~n + 12. 获取整数的二进制的最右边的1:n & (-n) 或 n & ~(n - 1)。例如 n = 010100, -n = 101100,那么n & (-n) = 0001003. 去除整数的二进制的最右边的1:n & (n - 1)。例如 n = 010100,n-1 = 010011,n&(n-1)原创 2015-01-13 18:48:27 · 6145 阅读 · 0 评论 -
整数的二进制表示中1的个数
给出通常能想到的方式,这两种方式在《C和指针》一书中给出。以下讨论的均为非负整数。/*该方法每次在循环中判断数的二进制最右一位是否为1(如果该数能不能被2整除)。每次循环后该数右移一位。因此遍历了数的二进制表示的每一位。*/int count_one_bits1(int value) { int count; for (count = 0; value != 0; value原创 2015-01-11 21:38:43 · 4667 阅读 · 0 评论 -
m个苹果放入n个盘子
题目描述放苹果问题:把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(注:5,1,1和1,1,5是同一种分法)解题分析:设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m) 当n1、有至少一个盘子空原创 2015-05-05 17:29:40 · 10848 阅读 · 1 评论 -
动态规划:计算字符串相似度
《编程之美》第223页。题目描述 许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程序。我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为:1.修改一个字符(如把“a”替换为“b”); 2.增加一个字符(如把“abdd”变为“aebdd”);3.删除一个字符(如把“travelling”变为“traveling”);比原创 2015-05-05 17:09:20 · 3619 阅读 · 0 评论 -
字符串合并处理(二进制位的倒序)
描述: 按照指定规则对输入的字符串进行处理。详细描述:将输入的两个字符串合并。对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标意思是字符在字符串中的位置。对排训后的字符串进行操作,如果字符为‘0’——‘9’或者‘A’——‘F’或者‘a’——‘f’,则对他们所代表的16进制的数进行BIT倒序的操作,并转换为相应的大写字符。如字符原创 2015-05-04 20:28:38 · 3039 阅读 · 0 评论 -
汽水瓶
描述: 有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?原创 2015-05-04 16:44:28 · 1370 阅读 · 0 评论 -
称砝码问题
题目描述有一组砝码,重量互不相等,分别为m1、m2、m3……mn;它们可取的最大数量分别为x1、x2、x3……xn。 现要用这些砝码去称物体的重量,问能称出多少种不同的重量。 Input测试数据第一行一个整数n(n),表示有多种不同的砝码; 第二行n个整数(中间用空格分隔),m1、m2、m3……mn,分别表示n个砝码的重量;(1) 第三行n个整数(中间用空格分隔),x1、x原创 2015-05-04 16:25:48 · 3382 阅读 · 1 评论 -
最长递增子序列
一、题目描述描述:N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1, T2, …, TK,则他们的身高满足T1 Ti+1 > … > TK (1 你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩原创 2015-05-02 20:40:57 · 13583 阅读 · 0 评论 -
动态规划:求最长公共子串/最长公共子序列
最长公共子序列和最长公共子串区别 最长公共子串(Longest Common Substring)与最长公共子序列(Longest Common Subsequence)的区别: 子串要求在原字符串中是连续的,而子序列则只需保持相对顺序一致,并不要求连续。例如X = {a, Q, 1, 1}; Y = {a, 1, 1, d, f}那么,{a, 1, 1}是X和Y的最长公共子序原创 2015-04-30 11:30:58 · 35752 阅读 · 0 评论 -
hash函数的基本知识
Hash函数也称为散列表,是一种常用的数据结构。哈希表优点:可以提供快速插入和查找操作,无论有多少数据项,插入与查找只需接近常量的实际:O(1)时间级。而且编程很容易实现。哈希表的缺点:它是基于数组的,数组一旦被创建,就难以拓展;某些哈希表的填充因子(填入的元素个数/哈希表长度)过大,性能会急剧下降。 Hash函数在多个领域均有应用,而在数字签名和数据库实现时又用的最多,比如基原创 2015-04-15 15:06:43 · 6372 阅读 · 1 评论 -
动态规划之钢条分割
长度i 1 2 3 4 5 6 7 8 9 10价格Pi 1 5 8 9 10 17 17 20 24 30上图分别是长度为i的钢条的价格;那么现在一根长度为n的钢条,求如何切割,使得利润最大?《算法导论》205页。如果只求最大利润的值,不需要知道分割过程,有以下两种方法:原创 2015-04-07 15:27:56 · 2196 阅读 · 0 评论 -
avl树的C++实现
//3avl_tree_c++.h#ifndef AVL_TREE_cplusplus_H#define AVL_TREE_cplusplus_H#include using namespace std;template class AvlTree{public: AvlTree():root(NULL) {} AvlTree(const AvlTree &rhs): r原创 2015-03-30 11:33:26 · 1489 阅读 · 0 评论 -
AVL树(Adelson-Velskii-Landis tree)
AVL树是一个“加上了额外平衡条件”的二叉搜索树。其平衡条件的建立时为了确保树的深度为O(longN)。AVL树要求任何节点左右子树的高度相差不超过1。插入操作:左-左插入和右-右插入需要单旋转; 左-右插入和右-左插入需要双旋转。原创 2015-03-27 10:34:31 · 1922 阅读 · 0 评论 -
基础排序算法总结
一、冒泡排序冒泡排序的普通思路: 比较相邻的两个元素,交换元素使得小元素在前、大元素在后。 第一次排序将对n个元素进行n-1次比较,将最大的元素放到了数组的最后边; 第二次排序将剩下的n-1个元素进行n-2次比较,将第二大的数放在数组的倒数第二个位置; 依次进行该过程; 第n-1趟则所有元素原创 2015-03-17 20:06:33 · 3080 阅读 · 0 评论 -
直接选择排序
直接选择排序和直接插入排序类似,都将数据分为有序的区域和无序的区域。所不同的是直接插入排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有序区,而直接选择排序是从无序区选一个最小的元素直接放到有序区的最后。void Swap(int &a, int &b) { int tmp = a; a = b; b = tmp;}void SelectSort(int a[], int原创 2015-03-17 16:22:50 · 1779 阅读 · 1 评论 -
冒泡排序的改进
通常的冒泡排序 假设按照升序排序。 设数组大小为n;比较相邻的两个数,如果第一个大于第二个,则交换两个数据;这样,第一个排序后,比较了n-1次,最大的数在数组末尾。然后n = n- 1,在n不为0情况下继续排序,否则排序完成。void bubble_sort1(int a[], int size) { int i; for (i = 0; i <原创 2015-03-17 11:32:01 · 2315 阅读 · 0 评论 -
红黑树操作及实现
红黑树性质 红黑树是广泛应用的平衡二叉搜索树之一(另外一种常见的平衡二叉搜索树是AVL树)。它是SGI STL唯一实现的一种搜索树;是关联容器的底部机制。 和AVL树所实现的平衡机制不同,但是同样适用了单旋转和双旋转操作修正树以保证平衡。 红黑树的性质: 1. 每个节点都被着上黑色或者红色。原创 2015-01-05 21:27:16 · 1889 阅读 · 0 评论 -
快速排序的几种常见实现及其性能对比
Hoare的变形版本(空穴法)快速排序算法是一种不稳定的排序算法。其时间复杂度为O(nlogn),最坏复杂度为O(n^2);快排的空间复杂度为O(logn),这个不确定正确。假设待排序的数组为a[],快速排序算法最常见的做法是将第一个元素设置为枢纽元。设置两个指针low和high,它们分别指向待排序的数组的低和高位:(1)high向左移动找小于枢纽的元素,找到后(找到的是a[high]原创 2014-12-22 19:11:54 · 11451 阅读 · 1 评论 -
归并排序及其空间复杂度的思考
对归并排序来说:如果对Merge的每个递归调用都声明一个临时数组,那么任一时刻可能会有logN个临时数组处于活动期,这对小内存机器是致命的。另一方面,如果Merge动态分配并释放最小量临时空间,那么由malloc占用的时间会很多。由于Merge位于MSort的最后一行,可以在MergeSort中建立该临时数组。因此在任一时刻只需要一个临时数组活动,而且可以使用该临时数组的任意部分;我们将使用和原创 2014-12-20 17:27:04 · 16087 阅读 · 5 评论 -
堆排序
对于小根堆来说,一般的思路是每次删除最小值,执行N次删除;每次将删除的元素拷贝到一个新的数组,那么新数组将按照从小到大的顺序排列。这里的主要问题是空间的:使用新数组,使存储空间增加了一倍。 一个技巧是:每次删除一个堆元素,堆大小会减少1。那么位于堆最后的那个空间可以用来存放刚刚被删除的元素。按照这种思路,不用额外的空间即可完成排序。 对小根堆,该方式排序完的数原创 2014-12-20 16:57:14 · 1733 阅读 · 0 评论 -
插入排序和希尔排序
插入排序:由N-1趟排序组成,第i趟排序保证位置0到i-1上元素是已经排好序的。在该算法代码实现中使用了可以减少元素交换次数的技巧:在for循环内,实现了数组元素移动而没有明显使用交换。位置i上的元素存储在tmp中,而位置i之前的所有更大的元素 都被向右移动一个位置;然后tmp被放置在正确的位置上。这个技巧与实现二叉堆和堆排序中所用的技巧相同(可以减少交换次数,加快速度),参考二叉堆的插入删除原创 2014-12-20 16:53:51 · 1487 阅读 · 0 评论 -
二叉堆的插入删除等操作C++实现
有几种明显的方法实现优先队列:1. 使用简单链表在表头以O(1)执行插入操作,遍历该链表需要O(N)。另一方法是始终保持表有序,插入操作代价为O(N),deleteMin花费为O(1)。2. 使用二叉查找树。插入、删除操作平均时间均为O(logN)。实现优先队列要删除最小元素,那么将会不断在左子树中删除,会损害树的平衡,会使右子树加重。这样,在最坏情况下,左子树为空,则树相当于链表,这样其原创 2014-12-19 15:05:56 · 3089 阅读 · 0 评论 -
二叉树遍历、插入、删除等常见操作
1.二叉查找树的创建2.二叉查找树清空3.二叉查找树查询4.查找最大值、最小值5.二叉查找树插入操作6.二叉查找树的删除操作7.分别使用非递归和递归方式(部分用多种方式)实现树的先序遍历、中序遍历和后序遍历原创 2014-12-03 17:27:55 · 15575 阅读 · 3 评论 -
链表的常见实现
版权所有,转载请注明出处,谢谢!http://blog.csdn.net/walkinginthewind/article/details/7393134链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力。链表的操作也离不开指针,指针又很容易导致出错。综合多方面的原因,链表题目在面试中占据着很重要的地位。本文对链原创 2014-11-24 20:54:14 · 5229 阅读 · 1 评论 -
Josephus约瑟夫问题及其变种
问题由来:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。原创 2014-11-21 11:18:29 · 6552 阅读 · 0 评论