算法题型浅谈
最大的几个数字问题
描述:
在许多数据中,找出最大的几个数字;而每次比较的容器(可装载数据长度)是有限的;如何快速找出
本质:
众多数据都需要依次进入有限容器进行比较,重点在于减少比较的次数或者说轮数,如何减少?分组比较,比较过的,已经有大小顺序的,将这些组的第一位或者前几位拿出来在比一次,此次比较最后的几位,那些组就可以不再比较了,因为该组最大的比不赢,小的也不行,所以这样就减少了比较的元素,排除了许多元素
组合顺序问题
描述:
在有限的字符串中(如a-g),组成1~4个字符串,如a,aa,aaa,aaaa,aaab…aaag这种排序下去,随机给出一个字符串,找出他的序号index
本质:
这是一个组合问题,排序组合有7的4次冪可能,排序在遍历会引入时间复杂度问题;转换一种思路,将多种可能转换为树的结构,高度为4,依次列出每种可能,然后在从中找出规律,而给出的字符串只需要找出他之前的数的节点个数即可
排序问题
纸牌出队
有限的n张纸牌,从牌顶到牌底序号分别是1、2、3、…n,按顺序从牌顶出牌,然后放入牌底,如纸牌1出队,纸牌2入牌底,纸牌3出队,纸牌4入牌底,直至出完;求出出牌的顺序;
如5张牌,1、2、3、4、5
出牌顺序:1、3、5、2、4
思路一:
很容易想到,将纸牌顺序组成一个链表,按照规则节点出队、节点放入队尾,依次出完即可;但是这需要不停的移动节点
思路二:
找规律,按照要求逐次遍历元素,如1~100,第一遍,出来的是13579…,第二遍是2、6、10,第三遍则是4、12…从这个当中找规律,规律如下:
我们规定一个步长step,即每次移动的距离,第一遍步长为1,然后分别是2、4、8…,每一遍都是能被开头数据整除后,得数为奇数的数字,比如第一遍:
step=1,第一个数据为first=1,以此除1,1/1 = 1, 2/1=2, 3/1 = 3…,除完后得数为奇数的出队,13579
第二遍step=2,还剩2、4、6、8、10、12…依次除地第一个元素2, 2/2=1,4/2=2,6/2=3为奇数的在出队
第三遍如上,就能得到出队顺序,代码如下:
void sort(int number[], int len){
int step = 1;
int i = 0, j = 0;
int value;
while(i < len){
j = i + step;
printf(" %d ", number[i]);
while(j < len){
value = number[j] / number[i];
if(value % 2 != 0){
printf(" %d ", number[j]);
}
j = j + step;
}
i = i + step;
step = step << 1;
}
}