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


    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("
    %s
    ", 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("
    %d
    ", cur_length);
        } else {
            get_str(last_start, last_length, str);
            printf("
    %d
    ", last_length);
        }
    }
    
    int main(int argc, char* argv[]) {
    
        find_str();
        return 0;
    }

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

  • 相关阅读:
    【请教】在vim中如何快速选中一个单词?并且让文本中的所有这个
    SQL中为了加强分类表的记录有效性,把主键和外键设计在了同一张表内
    JS不忘本之switch篇~建立一个菜单,并为菜单的参数来设置它的具体操作
    JS不忘本之JS类篇~类,方法,属性,子类,扩展方法在JS里的实现
    移入页面上空文本框时,让它变为焦点,移出清除焦点
    EF中数据优先,模型优先和代码优先
    关于ApplicationContext的初始化
    Linux下无线路由器的软件开发
    as3实现的拼图游戏
    AppWidgets
  • 原文地址:https://www.cnblogs.com/kongqueling/p/3216140.html
Copyright © 2020-2023  润新知