几个算法小题目--桶排序

1->比如给你一个数组,里面的数有200个,最大的数是1000,时间效率的重要性高于空间效率,那么你会采用哪种排序策略呢?能否达到O(n)

思路:对于这种问题,可能我们会想到很多种排序方法,冒泡排序,快速排序,希尔排序,堆排序,插入排序,选择排序以及归并排序;

可是仔细想想他们的时间复杂度:

冒泡排序中第n个数据分别比较n-1次,时间复杂度是O(n^2);复杂度太高;

快速排序,也是基于分治的思想,他的每次划分都至少把一个元素放在正确位置上,基本有序时间复杂度为O(n^2),最好情况O(nlogn);

希尔排序,需要定义步长的排序方法,对于大数据量的排序,比插入排序效率高很多,最好时间复杂度O(n),最坏时间复杂度O(n^2);

堆排序,对于大数据量查找最大值,最小值问题可以采用大顶堆,小顶堆方法,时间复杂度O(nlogn);

插入排序,时间复杂度,每个元素都要比较n-1次,每次都能把一个元素放在正确位置上,时间复杂度O(n^2);

选择排序,其中的直接选择排序,每次找一个最小元素,放在第一个位置,在选取剩下元素最小的,与第二个值交换,依次。。。第n趟要比较n-1次,时间复杂度O(n^2);

归并排序,基于分治的排序方法,先将待排序数组分为两个数组,依次类推,切分数组知道只剩一个数据单元,然后排序合并,时间复杂度,n(logn)。

都不是很满意题目的要求,所以换个思路:

首先定义一个整型数组B,由于待排最大值是1000,数组可以定义大小为1001,全部初始化为0,然后遍历待排序的数组,以待排数组中的数据值作为下标,更改B数组此下标的值+1,之后遍历B数组,相应不为0的小标就是待排序数组排序后的值。可能出现某下标的数值不为1,为n,说明待排数组出现了n次。

这叫做桶排序,时间复杂度O(n)。

2->现在给定一个整数K,问你如何确定这个数组里是否有两个整数的加和为K存在?时间复杂度O(n)

这道题的思路就是:假如sum= 10, 已知数组A为[3,4,5,7,9],首先定义一个整型数组B,全部初始化0,当遍历数组A时,每获取一个数组A中的元素K,都去判断以sum-K为下标的B数组中的值是否大于0,如果不是,说明还没出现与K相加为sum的那个数字,将B[K]加1,继续遍历下一个,依次类推,知道出现K且B[sum-K]也大于0,那么可以返回这组数字啦,他们就是在这个数组中第一个加和为sum的值。

有个思维定势:就是在内存没有限制的时候,字符型数组、整型数组排序的很多问题都可以用这样的一个数据结构存储处理。

3->给定一个字符数组,求它的子字符串中字母不重复的最长子串,例如abeomeabscqescan(求出结果为eabscq)

#include<stdio.h>
#include<stdlib.h>
void get_str(int start, int length, char*str) {
    int i=0;
    char p[16];
    for(i = start; i<length+start; i++) {
        p[i-start] = str[i];
    }
    printf("\n%s\n", p);
}

void find_str() {
    char str[16] = {"abeomeabscqescan"};

    int last_start=0, last_length=0;
    int cur_start = 0, cur_length = 0;
        
    int temp[26] = {0};
    int i=0;
    char *result;
    while(i<sizeof(str)) {
        if((temp[str[i]-'a'] +1) > 1) {
            //比较length
            if(last_length < cur_length) {
                    last_length = cur_length;
                    last_start = cur_start;
                    cur_length = 0;
                    cur_start = i;
                    i++;
            } else {
                cur_length += 1;
                i++;
            }
        }else {
            temp[str[i]-'a'] += 1;
            cur_length += 1;
            i++;
        }
    }
    if(last_length < cur_length) {
        get_str(cur_start, cur_length, str);
        printf("\n%d\n", cur_length);
    } else {
        get_str(last_start, last_length, str);
        printf("\n%d\n", last_length);
    }
}

int main(int argc, char* argv[]) {

    find_str();
    return 0;
}

返回eabscq~时间复杂度O(n);

posted @ 2013-07-25 23:24  ..孔雀翎..  阅读(711)  评论(0编辑  收藏  举报