
算法
LevinLin
本博客现只用于学习用,可能会转载他人的知识,若有涉及到您的版权问题,请与我联系。
> 飛雪迎春到﹐風雨送春歸
> 已是寒崖百丈冰﹐尤有花枝俏
> 俏也不爭春﹐只把春來報
> 待得山花爛漫時﹐他在叢中笑
展开
-
800个节点的完全二叉树共有多少个叶子节点?相反,已知叶子节点,求最多有多少个节点!
性质:叶子节点=度数2的节点+1证明:总节点数n,叶子节点n0,度数为1的节点n1,度数为2的节点n2那么:n=n0+n1+n2 n=n1+2*n2+1 //通过枝来看所以:n0=n2+1然后根据题意:800=2*n0-1+n1 对于完全二叉数n0等于1或0,这里肯定是1,OK,n0=400 再来一题,124个叶子节点的完全二叉树,最多有多少个节点?原创 2013-04-13 22:35:04 · 7398 阅读 · 2 评论 -
二分查找
#include #include int binaryFind(int arr[],int len,int key){ int low=0,high=len-1,mid; while(low <= high) { mid=(low+high)>>1; if(arr[mid]==key) return mid; if(key < arr[mid]) high=mid-1;原创 2012-09-16 21:50:40 · 504 阅读 · 0 评论 -
基数+快速排序
#include #include void pr_arr(int a[],int len){ int i=0; for(i=0;i<len;++i) { printf("%d ",a[i]); } printf("\n");}void swap(unsigned int *a,unsigned int *b){ if(*a !=*b) { *a^=*b; *原创 2012-09-16 21:48:45 · 661 阅读 · 0 评论 -
第三十六题:队伍比赛求出冠军,每轮淘汰的人不计较排名
/* * 谷歌笔试:n支队伍比赛,分别编号为0,1,2。。。。n-1,已知它们之间的实力对比关系,存储在一个二维数组w[n][n]中,w[i][j]的值代表编号为i,j 的队伍中更强的一支。所以w[i][j]=i或者j,现在给出它们的出场顺序,并存储在数组order[n]中,比如order[n]={4,3,5,8,1......},那么第一轮比赛就是4对3,5对8。.......胜者晋原创 2012-10-01 16:46:40 · 2157 阅读 · 1 评论 -
第十四题:在一个排序数组中查找一对数,使得其和等于某个值
/* ============================================================================ 题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。例如输入数组1、2、4、7、11、15和原创 2012-09-29 19:50:19 · 1832 阅读 · 0 评论 -
第十七题:在一个字符串中找到第一个只出现一次的字符。
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。/* ============================================================================ 查找一个字符串中,第一只出现一次的字符 思想:用一个Map来记数,Map[A]=2表示A字母为2个数 ===================原创 2012-09-29 20:59:46 · 924 阅读 · 0 评论 -
一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
/* * 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值比如{3,2,4,3,6}可以分成{3,2,4,3,6}m=1;{3,6}{2,4,3}m=2{3,3}{2,4}{6}m=3所以m的最大值为3 *///测试 以goal为目标,在groupId这个组,行得通吗?//a[]表示数组,n为长度,m表示要分成几组,sum表示总数,//groups原创 2012-09-29 16:33:49 · 4948 阅读 · 0 评论 -
第十一题:求二叉树任意两结点的最大距离
#include "bst.h"#include #include #define max(a,b) ((a)>(b) ? (a) : (b))/* ============================================================================ 求二叉树中任意两点的最大距离 ===================原创 2012-09-29 17:26:25 · 1126 阅读 · 0 评论 -
算法导论——矩阵链乘法
【问题描述】给定有n个连乘矩阵的维数,要求计算其采用最优计算次序时所用的乘法次数,即所要求计算的乘法次数最少。例如,给定三个连乘矩阵{A1,A2,A3}的维数分别是10*100,100*5和5*50,采用(A1A2)A3,乘法次数为10*100*5+10*5*50=7500次,而采用A1(A2A3),乘法次数为100*5*50+10*100*50=75000次乘法,显然,最好的次序是(A1A2原创 2012-09-28 21:31:07 · 2151 阅读 · 0 评论 -
动态规划——装配线调度
问题的描述:汽车生产工厂共有两条装配线,每条有 n 个装配站;装配线 i 的第 j 个装配 站表示为 Si,j,在该站的装配时间为 ai,j。一个汽车底盘进入工厂,然后进入装配 线 i(i 为 1 或 2) ,花费时间为 ei。在通过一条线的第 j 个装配站后,这个底盘来 到任一条线的第(j+1)个装配站。如果它留在相同的装配线,则没有移动开销; 如果它移动到另一条线上,则花费时间为 ti,j转载 2012-09-28 16:18:36 · 888 阅读 · 0 评论 -
数组乘积--求除自身外,其它数的乘积并放到result数组相应的位置
/* * 一个长度为n的整数数组result,满足result[i]=除input[i]之外所有数的乘积(不溢出),比如 * 输入input={2,3,4,5};输出 result={60,40,30,24}; *//* * 方法一:判断有0的情况,如果有0则其他都为0.如果没0,可使用先求全部乘积,再除以自身。 * 方法二:先保存i位置前的乘积到result[i],再用一原创 2012-09-29 10:01:47 · 2124 阅读 · 0 评论 -
将数字上调至8的倍数
不仅是8,2^N次方都是可以。解释:如输入9 ;那所求就是9+7-多余的部分,多余就是二进制的最后三位,所以答案是 ((m+7) & ~7) ps:最后三位为0一定是8的倍数。enum {_ALIGN = 8}; //设定上调边界为8(例如客户端输入30,调为32) static size_t round_up(size_t bytes){ //将bytes原创 2012-09-05 16:18:19 · 1843 阅读 · 0 评论 -
单链表交换相邻元素
#include #include typedef struct node{ struct node* next; int key;} Node;//交换相邻的元素,如果是交换两结点的值就很简单,但是交换结点的话就。。//以下是交换结点。//如 1 2 3 4 5 ==> 2 1 4 3 5Node* swapAdjacent(Node *head1){ if(head1=原创 2012-09-28 09:57:22 · 6360 阅读 · 0 评论 -
字符串分离 split
#include #include #include #include //申请二维数组char **new2arr(int v,int h){ char **dest; int i=0; assert(v>0 && h>0); dest=(char **)malloc(sizeof(char*)*v); for(i=0;i<v;++i) {原创 2012-09-10 14:27:36 · 711 阅读 · 0 评论 -
二分查找插入排序
#include #include void pr_arr(int a[],int len){ int i=0; for(i=0;i<len;++i) { printf("%d ",a[i]); } printf("\n");}//查找插入的位置int bFindToInsert(int *arr,int len,int key){ int low=0,high=le原创 2012-09-16 21:51:42 · 3434 阅读 · 0 评论 -
堆排序
#include #include void swap(int *a,int *b){ if(*a !=*b) { *a^=*b; *b^=*a; *a^=*b; }}// s表示源数组,len表示数组大小,target表示要调整点的位置void heapAdjust(int *src, int len, int target){ int rc = src[tar原创 2012-09-16 21:52:47 · 510 阅读 · 0 评论 -
MicroSoft 12个球一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球?那13个呢?
分三组:A(4) B(4) C(4)一,若A(4)==B(4) 那坏的在C(4)中。C1(3)与A(3)一称,相等,C2(1)是坏的。否则 假设C1(3)>A(3),那在C1中取两个一称,可知那个(重的)是坏的。二,假设A(4)>B(4), 分组A1(1)+B1(2) 与 A2(1)+B2(2) //第二步一定要求得 是两个球是坏!!!若A1(1)+B1(2) == A2(1)+B2(原创 2012-09-20 22:35:24 · 1627 阅读 · 2 评论 -
12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人 高,问排列方式有多少种?
12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第一排比对应的第二排的人高,问排列方式有多少种?思想:分析一下排列法,发现:每次安插第二排时,只要等第一排的选完了,再选最小值就行了。而选第一排时,只能从上次选的后一个开始选,且最后至少留count-1个数,count当前还剩多少个位置要安插!//=========================================原创 2013-04-11 21:36:25 · 2440 阅读 · 0 评论 -
判断一个整数是不是二的整数次幂 求某个数的二进制中1的个数
方法:i&(i-1) 如二进制1100 && 1011 =1000 相当于去掉最右边的1//求一个整数中二进制1的个数 --普通方法int Numof1(unsigned int i){ int count=0; while(i) { if(i&1) { ++count; } i>>=1; } return count;}int GetBitNum原创 2012-08-22 13:37:49 · 1657 阅读 · 0 评论 -
两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]…*a[N-1]/a[i];
问题描述:两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]…*a[N-1]/a[i];要求:1.不准用除法运算2.除了循环计数值,a[N],b[N]外,不准再用其他任何变量(包括局部变量,全局变量等)3.满足时间复杂度O(n),空间复杂度O(1)#include #include void pr_a原创 2013-04-10 21:10:30 · 1807 阅读 · 0 评论 -
一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间。
这个题目要求用O(n)的时间复杂度,这意味着只能遍历数组一次。同时还要寻找重复元素,很容易想到建立哈希表来完成,遍历数组时将每个元素映射到哈希表中,如果哈希表中已经存在这个元素则说明这就是个重复元素。因此直接使用C++ STL中的hash_set(参见《STL系列之六 set与hash_set》)可以方便的在O(n)时间内完成对重复元素的查找。 但是题目却在空间复杂度上有限制——要求转载 2012-12-10 23:06:15 · 9020 阅读 · 1 评论 -
求平均值 防溢出方法
int avg(int x, int y){ return (x & y) + ((x ^ y) >> 1);}解释:X+Y= (X^Y)+((X&Y)SO: (X+Y)/2==((X^Y)>>1)+(X&Y)原创 2012-10-26 19:03:44 · 2616 阅读 · 1 评论 -
求全排列(可重复)next_permutation
字典序列算法 字典序列算法是一种非递归算法。而它正是STL中Next_permutation的实现算法。我们来看看他的思路吧:它的整体思想是让排列成为可递推的数列,也就是说从前一状态的排列,可以推出一种新的状态,直到最终原创 2012-10-21 11:09:01 · 2595 阅读 · 0 评论 -
就地归并排序inplacMergeSort,空间复杂度O(1)
难度在就地归并:说看代码及注释。与上篇文章有点类似。//============================================================================//@lgh原创//============================================================================#i原创 2012-10-21 20:41:42 · 3061 阅读 · 1 评论 -
把数组中前后两段合并,后段的数间隔插在前段中。空间复杂度O(1)
数组类似如下:s[]="123456789abcdefghi" 前后各半,然后把它变成1a2b3c4d5e6f7g8h9i 思路:如简单点[1234,abcd] 如果把两个区间分别分为两半,[12,34]与[ab,cd] 把中间 34,ab这两部分rotate倒换一下,则变成[12,ab]与[34,cd],发现没,好像是两个子问题耶。OK,递归。但是如果是[12345,abcde]好像分原创 2012-10-21 20:33:17 · 1644 阅读 · 0 评论 -
已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10
int rand7() { return rand()%7+1; } int rand10(){ int x=0; do { x=(rand7()-1)*7+rand7(); } while(x>40); return x%10+1;} 分析:要保证rand10()在整数1-10的均匀分布,可以构转载 2012-10-19 21:40:13 · 4606 阅读 · 2 评论 -
数据循环移位(左右区间交换)
设计一个算法,把一个含有N个元素的数组循环右移K位。要求时间复杂度为O(N)。#include #include void Reverse(char *arr, int b, int e);void RightShift(char *arr, int N, int k);int main(void){ char a[]="abcd1234"; RightShift(a,siz原创 2012-08-15 16:19:28 · 1604 阅读 · 0 评论 -
一个整型数组里除了两个数字之外,其他的数字都出现了两次。查出其他两个只出现一次的数
#include using namespace std;/* * 61.找出数组中两个只出现一次的数字题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。 */void findTwoNumsWithOthersHas2Times(int s[],int len){ if(len<2原创 2012-09-21 11:46:22 · 3478 阅读 · 0 评论 -
请设计一个队列FIFO,要求包含min max mid函数
转载请注明出处:http://blog.youkuaiyun.com/shandianling/article/details/7997163解释:min()要求返回队列中的最小值 max()要求返回队列中的最大值 mid()要求返回队列中倒数第(size()+1)/2小的值。说白了就是把队列变成有序后最中间那个值。思想:把两个双向链表,一个保存队列顺序,一个是有序的。然后就整成一个链表原创 2012-09-19 17:47:33 · 1720 阅读 · 0 评论 -
分离字符串中的*
函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移,但不能改变非'*'字符的先后顺序,函数返回串中字符'*'的数量。 如原始串为:ab**cd**e*12,处理后为*****abcde12,函数并返回值为5。(要求使用尽量少的时间和辅助空间)想法:有点像上篇中的删除 字符串的数字并压缩。 解法:从后到前,遇到字母(非*),就与*交换。#include #incl原创 2012-08-28 16:10:47 · 1370 阅读 · 0 评论 -
删除字符串中的数字并压缩。
两个指针,使一个指针指向数字,一个指针指向字母。#include #include char* delNumsOfStr(char *str){ if(str ==NULL) return NULL; char *pi,*pk; pi=pk=str; while(*pi != '\0') { if(*pi '9') { *pk++=*pi++; } else原创 2012-08-28 15:04:20 · 1077 阅读 · 0 评论 -
求数组中最长递增子序列
#include #include #include int min(int arr[],int len);int max(int arr[], int len);void pr_arr(int arr[], int len);void pr_mostIncreaseList(int arr[], int MaxCount[], int len, int curi, int原创 2012-08-23 15:33:57 · 624 阅读 · 0 评论 -
对字符串中的字母进行组合
0 1背包问题 先把字符串去重,并记录每个字母相应的个数.设组合的结果为comb(s,strCount,idx,aux) ,s表示去重的字符串,strCount表示对应的个数,idx表示当前位置,aux表示当前位置取了几个数那么comb(s,strCount,idx,aux)= 当aux[idx]分别为0...n时comb(s,strCount,idx+1) ;/* ======原创 2012-09-02 14:04:17 · 1054 阅读 · 0 评论 -
求N!(N的阶乘) 中最后有几个0
方法:求N! 中质因子5的个数,即能被5整除多少次。说明:相当于求10的个数==5*2的个数 由于5的个数N!中5的个数==[N/5]+[N/5^2]+[N/5^3]+...//太大的话会溢出的,只能算12!以下。unsigned int factorial(unsigned int n){ if(n==0 || n==1) return 1; else retu原创 2012-08-22 15:01:03 · 3508 阅读 · 0 评论 -
求N!的二进制表示中最低位1的位置 ->求 N!的质因子2的个数
说明:相当于求 N!的二进制表示最后有几个0 (与上篇中求N!十进制表示 最后有几个0 相似)即求 N!的质因子2的个数 == [N/2]+[N/2^2]+[N/2^3]+....然后+1就是得到位置了。(PS:位置从1开始算)求 N!的质因子2的个数的另一个方法:N!含有质因数2的个数,等于N减去N的二进制表示中1的个数#include #include //太大原创 2012-08-22 16:43:05 · 2255 阅读 · 0 评论 -
最长公共子序列(LCS)
先介绍LCS问题的性质:记Xm={x0, x1,…xm-1}和Yn={y0,y1,…,yn-1}为两个字符串,而Zk={z0,z1,…zk-1}是它们的LCS,则:1. 如果xm-1=yn-1,那么zk-1=xm-1=yn-1,并且Zk-1是Xm-1和Yn-1的LCS;2. 如果xm-1≠yn-1,那么当zk-1≠xm-1时Z是Xm-1和Y的LCS;3. 如果xm-1转载 2012-08-20 20:50:30 · 3979 阅读 · 0 评论 -
在从1到n的正数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。当最高位为1时:如:1234 ,1的个数记为f(n)分为两段,1~999,1000~1234 第一段:1~999 的个数 1*3*(10^2); 其中1为最高位,3为(长度-1),2为(长度-2)第二段:1000~1原创 2012-08-19 23:15:35 · 1727 阅读 · 0 评论 -
大数相加 相乘
用字符串保存两个大数。 把加法分解成: 一,同一位上为 (a+b)%10 二,进位(a+b)/10 ,三,把第一数+进位感觉是递归了。但可以用循环在代替。 大数相乘也差不多,第二数的每一位数都与第一个数每一位相乘,然后相加起来.以下我们假设两个字符串里都是数字,之里不做判断了.为了解题方便,我还把数字都移到数组的右端,方便相加.不足是会浪费一些时间 #include #inc原创 2012-08-28 21:25:20 · 660 阅读 · 0 评论 -
求两个整数的最大公约数,算法原理辗转相除法 原理: GCD (x,y) = GCD(y,x%y)
若求:最小公陪数= X*Y / GCD(X,Y)#include #include #include //递归int gcd1( int m, int n){ int r; if(0==(r=m%n)) return n; return gcd1(n,r);}//非递归int gcd2(int m,int n){ while(m!=0 && n!=0) { if原创 2012-08-17 11:10:52 · 6422 阅读 · 0 评论 -
随机打印1-100要求不重复
随机打印1-100 的数,每个只能打印一次#include #include //随机打印1-100 void pr_rand(int n){ int i; int a[n]; //init for(i=0;i<n;i++) { a[i]=i+1; } for(i=n-1;i>0;i--) { swap(a,rand()%(i+1),i); } rdump(a原创 2012-08-17 10:31:45 · 1156 阅读 · 0 评论