IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 三、最大间隙(线性时间算法) -> 正文阅读

[数据结构与算法]三、最大间隙(线性时间算法)

实验时间:10.28

目录

Puzzle 最大间隙问题

鸽笼原理

源代码:(只需要修改这几个参数即可)


Puzzle 最大间隙问题

给定 n 个无序实数 ,求 n 个实数在实轴上相邻 2 个数之间的最大差值,要求线性的时间算法。

例如: 4? 11? 1? 9? 20? 2? 17

输出: 6

首先想到的就是排序,然后求差值,但是我目前已知的最快的排序算法,排序时间复杂度最少也要O(nlongn),因此只能使用别的巧妙算法了。

鸽笼原理

拓展鸽笼原理(抽屉原理),即为桶排序,在输入过程中找出数据的最大值max与最小值min_,在【min,max】区间内,将最大值与最小值之间进行均分成n-1份,每个区间的大小为 len = (max?- min)/(n-1),即此时为n-1个桶,将最大值最小值人为放置于第一个桶和最后一个桶中,分别代表了各自桶的下限和上限。根据这个判断剩余的n-2个元素放置的桶的位置,因为有n-1个桶需要放置n-2个元素所以根据抽屉原理必定有一个桶是空的,所以,最大间隙一定产生在两个不同区间之间(即两个桶之间,就是跨区间的数才可能产生最大的间隙 ),故最大的间隙一定是一个桶所放数据的最小值与另一个桶所放数据的最大值之间的差值。

简述算法过程:

桶需要一个上界,一个下界,一个次数,判断是否为空;

遍历元素找到最大值,最小值;

剩下 n - 2个数等分的放入 n - 1个桶,肯定有一个桶为空;

按顺序,求出所有空桶之间的上下界之差,然后选择一个最大差值即可。

实验结果(含时间、空间、输出结果):

?

源代码:(只需要修改这几个参数即可)


实验数据链接:

#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>

using namespace std;

//FileNum为访问的文件数量,NumSize 为文件数据大小
const int FileNum = 3, NumSize = 10000;

//桶
struct Bucket {
    int high;//上界
    int low;//下界
    int count;//次数,是否为空
};

class Env {
public:
    int data[NumSize];
    int pointer_max = 0;
    int pointer = 0;
    string s = "0";

    Env(string str) {
        s = str;
        // test0.csv test1.csv test2.csv  共3个测试用例,请依次测试
        cout << "文件 " << s << endl;
        ifstream file("test_data/test_" + s + ".csv", ios::in);
        if (!file.is_open())
            cout << " 文件打开失败!" << endl;

        string temp;
        while (getline(file, temp)) {
            data[pointer_max] = stoi(temp);
            pointer_max++;
        }
        file.close();
    }
};

// 所有的代码都需要写在 Algo 类内,自行定义其他需要的变量或函数
class Algo {
public:
    Algo() {
        cout << "algo ok" << endl;
    }

    int run(Env& env) {
        //在此写入你的代码
        //env.data 为目标数组

        //遍历元素找到最大值,最小值;
        //剩下 n - 2个数等分的放入 n - 1个桶,肯定有一个桶为空;
        //按顺序,求出所有空桶之间的上下界之差,然后选择一个最大差值即可。
        int max = env.data[0], min = max;
        for (const auto& i : env.data) {
            if (i > max) {
                max = i;
            } else if (i < min) {
                min = i;
            }
        }
        cout << "max:\t" << max << "\nmin:\t" << min << '\n';

        Bucket a;
        a.count = 0;
        a.high = min;
        a.low = max;
        vector<Bucket> b;

        //初始化 n - 1个桶
        for (size_t i = 0; i != NumSize - 1; ++i) {
            b.push_back(a);
        }

        //遍历元素,
        for (int i = 0, index = 0, temp = env.data[i]; i != NumSize; temp = env.data[i], ++i) {
            //找到下标
            index = (NumSize - 1) * (temp - min) / (max - min);
            b[index].count += 1;
            if (temp > b[index].high) {//更新上界
                b[index].high = temp;
            }
            if (temp < b[index].low) {//更新下界
                b[index].low = temp;
            }
        }

        //res记录结果,tempHigh 记录前一个非空桶的上界
        int res = 0, tempHigh = 0;
        bool isEmpty = false;
        for (auto i = 0; i != b.size(); ++i) {
            //cout << b[i].count << '\t' << b[i].high << '\t' << b[i].low << '\t' << endl;
            if (b[i].count) {//不为空,记录high的值
                //桶 非空 并且 当前桶的下界,减去,前一个的非空桶的上界,即为差值,然后判断,找到最大的差值
                if (isEmpty && (b[i].low - tempHigh) > res) {
                    res = b[i].low - tempHigh;
                }
                //恢复状态,桶 不为空
                isEmpty = false;
                tempHigh = b[i].high;//记录前一个非空桶的上界
            } else {//桶 为空,
                isEmpty = true;
            }
        }
        cout << "最大间隙为:\t" << res << endl;
        return 0; //修改为返回正确的结果
    }
};

int main() {
    Env* env;
    for (int i = 0; i != FileNum; i++) {
        env = new Env(to_string(i));
        Algo algo;
        time_t start = clock();
        algo.run(*env);
        time_t end = clock();
        cout << "程序耗时: " << double(end - start) / CLOCKS_PER_SEC << " ms" << endl;
        cout << "占用内存:" << sizeof(algo) << " byte" << endl << endl;
        delete env;
    }
    return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-10 12:39:06  更:2021-11-10 12:40:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:18:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码