有趣的题目-二

给你N个数,要求在O(n)时间复杂度内,求出在有序情况下,两个相邻数的最大差值。【原题差不多是对于任意一个数都有和他最接近的数,要求你求这种最大的距离】

我们来一点一点地思考:

1.枚举:对于每一个数,扫描一遍所有的数,得到离他最近的数,更新最大差值,复杂度O(N^2)。

2.排序:整个数组快速排序一遍,再线性扫一遍,更新最大插值,复杂度O(NlogN)。

3.思想依旧是从排序出发,虽然基于比较的排序算法时间复杂度是不可能低于O(NlogN)的,但是我们也有不基于比较的排序,他们的复杂度和数据状况有关-基数排序、计数排序、桶排序。

我们需要的值是在有序情况下才能得出的,我们可以不排序,但是得借助一些有序的东西-桶。

让我们先做一些假设,n个数,数据范围是[min,max]。

A.假设这n个数在范围区间上均匀分布,并且(max-min)%n==0。

那么我们可以借用分块的思想,block=(max-min)/n,(index-min)/block就可以得到index位置的元素是归属于哪个桶的。然后因为这些元素是均匀分布的,所以一个桶内指挥归属一个元素。线性扫一遍将元素归位后,线性扫一遍更新最大差值。

B.让我们把假设弱化。假如n个数不会均匀的分布呢。假设不均匀分布,那么至少会有两个元素会在归位后并在一个桶里,此时会产生一个空桶。我们对桶维护两个值,min-桶内元素的最小值,max-桶内元素的最大值,我们可以简单分析后得知:

1)第i号桶的max和第i+1号桶的min在排序后一定是相邻的

2)由于有一个空桶,那么这个最大的值一定不会是一个桶内的元素产生,因为桶内元素的最大差值是<=block-1的,而空桶左右两个桶,前一个的max的后一个的min的差值是一定>=block的。

3)此方法一定有解:无解的情况只能是所有的元素都在一个桶内,但是由于我们是把整个规模区间划分成n份的,min在第一个个桶,max在第n个桶,因此不可能满足所有的元素都在一个桶内。

4)最大的元素值并不一定是空桶左右两个最近非空桶的差值,假设是一个空桶,那么他左右非空桶的邻近元素元素的最小差值为block,但是也可能存在这种情况,两个相邻的非空桶,各只有一个数,左边的桶内存放的是这个桶对应的区间的最小值,右边的桶内存放的是这个桶对应的区间的最大值,那么他们作为两个相邻元素,差值为2*block-1。

小总结:空桶的存在是为了去除同一个桶内存在最大差值的可能性。

因此,当元素归位后,我们遍历所有的桶,用前一个非空桶的max和后一个非空桶的min的差值更新最大差值即可。

C.这是最后一个弱化了,(max-min)%n!=0,也就是说,最后一个桶的跨度区间可能会超过block。那么在这种情况下,有可能在最后一个桶里,会出现两个相邻元素,并且他们的差值是超过block的,所以此时即使前面有空桶都不能免去此种情况的可能性。

办法:原本分配N个桶改成分配N+1个桶,但是block依旧保持block=(max-min)/n,于是,最后一个桶内装的是以max为右端值的,且桶内元素跨度严格<block的桶,并且由于是N+1个桶,因此一定是在第1和第n+1号桶中间至少会有一个空桶,而空桶的存在除去了同一个桶内有最大差值的可能性。

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int n,Max=0xffffffff,Min=0x7fffffff,Arr[105],large[105],small[105],to,lastMax,Maxdif=0xffffffff;
bool isNone[105]; 
int belong(int value){
    return (value-Min)*(n+1)/(Max-Min);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&Arr[i]);
        Min=min(Min,Arr[i]);
        Max=max(Max,Arr[i]);
    } 
    if(Min==Max){//最大值和最小值相等 
        printf("0");
        return 0;
    }
    large[0]=small[0]=Min;
    large[n]=small[n]=Max;
    isNone[0]=isNone[n]=true;
    for(int i=1;i<=n;i++){
        to=belong(Arr[i]);
        if(!isNone[to]){//没有元素 
            isNone[to]=true;
            large[to]=small[to]=Arr[i];
        }else{
            large[to]=max(large[to],Arr[i]);
            small[to]=max(small[to],Arr[i]);
        }
    }
    lastMax=large[0]; 
    for(int i=1;i<=n;i++){
        if(isNone[i]){
            Maxdif=max(Maxdif,small[i]-lastMax);
            lastMax=large[i];
        }
    }
    printf("%d",Maxdif);
    return 0;

### 关于TF-IDF算法的相关练习题 以下是几道与TF-IDF算法相关的经典题目,这些问题可以帮助深入理解和应用该算法: #### 题目1:计算给定文档集合中某个单词的TF-IDF值 假设有一个由三个文档组成的语料库: - 文档1:“机器学习是一门非常有趣的学科” - 文档2:“深度学习是机器学习的一个分支” - 文档3:“人工智能涵盖了机器学习和深度学习” 目标是计算单词“机器学习”的TF-IDF值。 提示:先分别计算每个文档中的TF值和整个语料库中的IDF值[^1]。 --- #### 题目2:手动实现TF-IDF算法 编写一段Python代码,用于计算一组文档中所有单词的TF-IDF值。输入是一个列表形式的文档集,输出是一个字典,键为单词,值为其对应的TF-IDF分数[^2]。 ```python from collections import Counter import math def compute_tf_idf(documents): tf_scores = [] idf_scores = {} # 计算TF for doc in documents: word_count = Counter(doc.split()) total_words = sum(word_count.values()) tf_doc = {word: count / total_words for word, count in word_count.items()} tf_scores.append(tf_doc) # 计算IDF num_docs = len(documents) all_words = set([word for doc in documents for word in doc.split()]) for word in all_words: df = sum(1 for doc in documents if word in doc.split()) idf_scores[word] = math.log(num_docs / (df + 1)) # 平滑处理 # 合并TF和IDF tfidf_scores = [{word: tf * idf_scores.get(word, 0) for word, tf in doc_tfs.items()} for doc_tfs in tf_scores] return tfidf_scores documents = ["机器 学习 是 一门 非常 有趣 的 学科", "深度 学习 是 机器 学习 的 一个 分支"] result = compute_tf_idf(documents) print(result) ``` --- #### 题目3:解释TF-IDF的作用及其应用场景 描述TF-IDF的核心思想,并列举至少三种实际应用场景。例如,在搜索引擎、推荐系统或情感分析等领域中是如何利用TF-IDF的? 答案要点:TF-IDF通过衡量单词的重要性来突出关键词[^3]。其常见应用场景包括但不限于: 1. **搜索引擎排名优化**:提高重要关键词的权重。 2. **文本分类**:帮助区分不同类别的文档特征。 3. **信息检索**:快速定位最相关的文档。 --- #### 题目4:比较词袋模型(BOW)与TF-IDF模型 阐述词袋模型(Bag of Words)和TF-IDF的主要区别,并讨论各自的优缺点[^4]。 答案要点: - BOW仅统计单词出现次数,忽略了单词的重要程度;而TF-IDF综合考虑了词频和逆文档频率。 - 缺点方面,BOW可能导致高频无意义词占据主导地位,而TF-IDF则能有效降低这类词的影响。 --- #### 题目5:解决过拟合问题 在使用SVM或其他复杂模型时,如果引入过多基于TF-IDF的特征可能会导致过拟合现象,请说明原因及解决方案。 答案要点:当特征维度过高时,训练数据不足以覆盖所有可能性,从而引发过拟合。可以通过降维技术(如PCA)、正则化手段或者减少特征数量等方式缓解此问题。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值