随笔分类 - 算法
摘要:一棵普通树,树中的结点没有指向父节点的指针,求一棵普通树的两个结点的最低公共祖先。代码如下,我太懒没有加注释,大家自己看吧! 1 #include 2 #include 3 #include 4 using namespace std; 5 6 struct TreeNode /...
阅读全文
摘要:没有啥好解释的啦,关键是要考虑所有的情况,比如正负号,溢出,输入等。 1 enum Status {kValid = 0 , kInvalid}; 2 bool g_nStatus = kValid ; 3 4 int StrToInt(const char* str) 5 { 6 g_n...
阅读全文
摘要:不用新的变量,交换两个变量的值。比如有2个变量a , b ,我们希望交换他们的值。下面介绍两种不同的解法:第一种:基于加减法a = a + b ; //先让a等于和b = a - b ; //和减去原来b的值得到原来a的值,赋值给ba = a - b ; //和减去改变后b的值(原来a的值)得到原...
阅读全文
摘要:写一个函数,求俩个整数之和,要求函数体内不得使用+、-、*、/ 四则运算符合。看到题目,我们知道,现在只有位运算可以用了,那就用位运算吧。第一步:对2个数的每一位相加,但不进位,我们可以用异或运算完成。第二步:找到进位的位置,并计算进位的值,我们先用与运算可以找到位置,然后左移一位,得到进位的值(比...
阅读全文
摘要:把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s。输入n,打印出s的所有可能的值和出现的概率。解法二:基于循环求骰子点数,比递归算法更加高端大气上档次具体代码如下,有详细注释。 1 ////////////////基于循环求骰子点数////////////////////////////////...
阅读全文
摘要:把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s。输入n,打印出s的所有可能的值和出现的概率。
解法一:基于递归求骰子点数。
阅读全文
摘要:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。
菜鸟的写法是顺序扫描,时间复杂度是O(n2)。下面给出一种大牛的写法,时间复杂度只需O(n)。
阅读全文
摘要:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1).
例如:输入{2,7,3,10,3,2,5,5} , 输出 7 和 10 。
大家首先想到的是顺序扫描法,但是这种方法的时间复杂度是O(n2)。接着大家又会考虑用哈希表的方法,但是空间复杂度不是O(1)。
应该怎么做才能即满足时间复杂度是O(n)又满足空间复杂度是O(1)的要求呢?
我们可以想一想“异或”运算的一个性质。任何一个数字异或它自己都是0 , 那么我们依次异或数组中的每一个数字,得到的结果就会是只出现一次的2个数字的异或结果。
因为这两个数字不同,所以异或结果肯定不为0,且能够区分开这两个数字的地方就是异或结果中为1的位。假设异或结果中从右向左数第n位为1,那么我们就可以把原来数组中的数字按照第n位是否为1分为两部分,每一部分就会只包含一个只出现一次的数字,且其他的数字都是成对出现。接下来只要分别对这两个数组求异或,就能找出每部分只出现一次的数字。
阅读全文
摘要:二叉树中任意左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
两种解法。
第一种:菜鸟的解法,出现重复遍历,时间复杂度高。
第二种:大神的解法,只遍历一次,高端大气上档次。
阅读全文
摘要:多的不解释了,这里有两种解法。
第一种:一般的解法。
第二种:大神的解法,代码简洁高效。
阅读全文
摘要:统计一个数字在排序数组中出现的次数。例如输入{2,2,2,2,2,3,5,5}和数字2,输出5.
常规的顺序扫描法时间复杂度是O(n),可以进一步优化。用二分查找的方法进行查找可以把时间复杂度降为O(logn)。
阅读全文
摘要:输入两个链表,找出他们的第一个公共结点。思想:我们可以先遍历一次得到分别得到两个链表的长度,然后计算得出长度差n,那么让较长的链表先走n步,然后两个链表一起向后走,直到两个指针指向同一个结点。这个结点就是我们要找的 结点。
阅读全文
摘要:在数组中的两个数如果前面一个数大于后面的数字,则这俩个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
例如:数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6)(7,5)(7,4)(6,4)(5,4)。
有两种方法:
第一种:顺序扫描法,时间复杂度是O(n2)。代码略。
第二种:运用归并排序的方法。思想是:
把数组递归的分成子数组,统计出相邻子数组的逆序对,统计过程中需对数组进行排序,防止重复统计。
阅读全文
摘要:在字符串中找出第一个只出现一次的字符。如输入:“aabcdc”,则输出b 。
思路:我们可以把数组当做一个简单的哈希表来用,把每个字母的ASCII码值作为在数组中的位置(下标),数组中存储的是该字符出现的次数。这样我们就创建了一个以字符ASCII码为健值的哈希表。
阅读全文
摘要:只包含因子2,3,5的数称作丑数。要求按从小到大的顺序输出指定数量的丑数。
有2中方法:
第一种:用穷举法,从最小的1开始判断穷举,是丑数就输出,否则继续循环判断。判断的方法是:如果一个数能被2整除,我们把他连续除以2;如果能被3整除,我们把他连续除以3;如果能被5整除,我们把他连续除以5。如果最后得到的值为1,那么这个数就是丑数。
第二种:用空间换时间,创建一个数组,里面的数字是排好序的丑数,下一个丑数是前面丑数乘以2、3、5得到的大于当前最大丑数的最小一个数。和第一种思路相比,第二种思路不需要在非丑数上做任何计算,因此时间效率会明显提升,但增加了空间消耗。
阅读全文
摘要:我们先把数组中的整数转换成字符串,在函数compare中定义比较规则,并根据该规则用库函数qsort排列。最后把排序好的数组中的数字依次打印出来,就是该数组中数字拼接出来的最小数字。这种思路的时间复杂度是O(nlogn)。
阅读全文
摘要:输入一个整数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的个数,然后去掉最高位递归的求剩下位数中1出现的个数。时间复杂度是O(logn)。
阅读全文
摘要:输入n个数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8 这8个数,则最小的4个数是1,2,3,4.
解法一:O(n)的算法,只有当我们可以修改输入数组时可用
解法二:O(nlogk)的算法,特别适合处理海量数据
阅读全文
摘要:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入数组:{1,3,3,2,3,2,3,3,2}。由于2在数组中出现了5次,超过数组长度的一半,因此要输出2。
有两种解法:
第一种方法是基于快速排序算法的原理,边排序边判断是否符合输出条件。这种方法的代码我因为没有保存,在电脑蓝屏之后全部消失了·······~~~~(_)~~~~ 呜呜。
第二种方法是根据数组特点找出的算法,时间复杂度为O(n),且不用改变数组本身结构。
阅读全文
摘要:八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。
阅读全文