首页 > 试题广场 >

最大差值

[编程题]最大差值
  • 热度指数:2468 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
给定一个未排序的数列,找到此数列在已排序状态下的两个相邻值的最大差值,少于两个值时返回0。例如:给定数列 [1,3,2,0,1,6,8] 则 最大差值为3。注意:请尽量使用时间复杂度为O(n)的方案。

输入描述:
第一行输入单个整数N作为数列的大小,第二行输入所有数列中的元素M,共N个。0 < N <= 1000000, 0 < M < 2100000000


输出描述:
数列的最大差值
示例1

输入

3
1 10 5

输出

5
///桶排序,题目样例k有问题,搞的数组越界,坑
import java.util.*;

public class Main {

    public static void main(String[] args) {
       Scanner scan=new Scanner(System.in);
       while(scan.hasNext()){
           int k= Integer.valueOf(scan.nextLine());
           String[]str=scan.nextLine().split(" ");
           int[] data=new int[str.length];
           for(int i=0;i<str.length;i++)
               data[i]=Integer.valueOf(str[i]);
           k=data.length;
           int max=-1;
           int min=Integer.MIN_VALUE;
           for(int i=0;i<data.length;i++){
               data[i]=data[i];
               max=Math.max(max,data[i]);
               min=Math.min(min,data[i]);
           }
           System.out.println(get(min,max,data));
       }
    }
    public static int get(int min,int max,int[] data){
        Good[]arr=new Good[max/10000+1];
        for(int i=0;i<arr.length;i++)
            arr[i]=new Good();

        for(int i=0;i<data.length;i++){
            int index=data[i]/10000;
            arr[index].list.add(data[i]);
        }
        int ans=0;
        for(int i=0;i<arr.length;i++){
            Collections.sort(arr[i].list);
        }
        int tem=min;
        for(int i=0;i<arr.length;i++){
            List<Integer> mylist=arr[i].list;
            if(mylist.size()>0)
                ans=Math.max(ans,mylist.get(0)-tem);
            for(int j=1;j<mylist.size();j++){
                int temans=mylist.get(j)-mylist.get(j-1);
                ans=Math.max(ans,temans);
            }
            if(mylist.size()>0)
                tem=mylist.get(mylist.size()-1);
        }
        return ans;
    }

}
class Good{
    List<Integer> list=new ArrayList<>();
}

编辑于 2019-04-17 22:58:11 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int N;
    cin >> N;
    int a[N];
    for (int i = 0; i < N; i++)
    {
        cin >> a[i];   
    }
    sort(a,a+N);      //升序排列
    int ans = 0;    //ans记录最大差值
    for (int i = 0; i < N-1; i++)
    {
        ans = max(ans,abs(a[i+1]-a[i]));  
    }
    cout << ans << endl;
    return 0;
}

编辑于 2019-01-09 23:24:47 回复(2)
#include <bits/stdc++.h>
using namespace std; 
int main()
{
    long long n,m[1000001],res=0;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>m[i];
    sort(m,m+n);
    for(int i=1;i<n;i++)
        res=max(res,m[i]-m[i-1]);
    cout<<res<<endl;
    return 0;
}

发表于 2019-06-18 10:22:01 回复(0)
//O(n)的话可以使用桶排序,空间换时间
//如下代码是先O(n)sort成升序后进行差值检验
#include <bits/stdc++.h>
using namespace std;
class Solution{
public:
    int get_ans(vector<int>& nums){
        base_sort(nums);
        int res=0;
        //找两者之间的差值即可
        for(int i=1;i<(int)nums.size();++i)
            res=max(res,nums[i]-nums[i-1]);
        return res;
    }
private:
    //计数+放桶 ,总体思想就是从低位开始每位进行比较排序,一直放到最高位
    void base_sort(vector<int>& nums){
        int base=10,exp=1; //base表示10进制,可自己修改
        vector<int> vec(nums.size()); //辅助数组
        int max_num=*max_element(nums.begin(),nums.end());
        while(max_num/exp>0){
            vector<int> cnt(base,0); //用于计数
            for(auto num:nums)
                cnt[(num/exp)%base]++;
            for(int i=1;i<(int)cnt.size();++i)
                cnt[i]+=cnt[i-1]; //累加计数
            for(int i=(int)nums.size()-1;i>=0;i--)
                vec[--cnt[(nums[i]/exp)%base]]=nums[i]; //放桶,但是这里注意序号,因此先进行--
            for(int i=0;i<(int)nums.size();++i)
                nums[i]=vec[i]; //放回到原来的数组
            exp*=10; //往高位走
        }
    }
};
int main(){
    int N;
    cin>>N;
    int cur;
    vector<int> nums;
   while(~scanf("%d",&cur))
        nums.push_back(cur);
    if((int)nums.size()<2){
        cout<<0;
        return 0;
    }
    Solution sol;
    cout<<sol.get_ans(nums);
    return 0;
}

发表于 2019-03-04 10:52:59 回复(0)

python两行解法。

注意第一个输入不是数组的长度,不是数组的长度!!!!如果用利用它来遍历数组,会出现越界的情况。太坑了吧

mother_***er, arr = int(input()), sorted(map(int, input().split()))
print(max(map(lambda c: arr[c] - arr[c - 1], range(1, len(arr)))) if len(arr) > 1 else 0)
编辑于 2019-02-24 19:41:05 回复(6)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 桶排序
 * @author wylu
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        String[] strs = br.readLine().split(" ");
        n = strs.length;
        int[] a = new int[n];
        int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
        for (int i = 0; i < n; i++) {
            a[i] = Integer.parseInt(strs[i]);
            if (a[i] < min) min = a[i];
            if (a[i] > max) max = a[i];
        }

        if (n < 2 || max == min) {
            System.out.println(0);
            return;
        }

        //每个桶是否有值
        boolean[] hasNum = new boolean[n + 1];
        //每个桶的最小值
        int[] low = new int[n + 1];
        //每个桶的最大值
        int[] high = new int[n + 1];
        for (int num : a) {
            int idx = getBucketIndex(num, n, max, min);
            low[idx] = hasNum[idx] ? Math.min(low[idx], num) : num;
            high[idx] = hasNum[idx] ? Math.max(high[idx], num) : num;
            hasNum[idx] = true;
        }

        int res = 0, lastMax = high[0];
        for (int i = 1; i <= n; i++) {
            if (hasNum[i]) {
                res = Math.max(res, low[i] - lastMax);
                lastMax = high[i];
            }
        }
        System.out.println(res);
    }

    private static int getBucketIndex(long num, long n, long max, long min) {
        return (int) ((num - min) * n / (max - min));
    }
}

发表于 2019-01-23 15:49:51 回复(0)
package main

import (
    "fmt"
    "sort"
    "os"
    "bufio"
)

var in=bufio.NewReader(os.Stdin)

func main() {
    var n int
    fmt.Scan(&n)
    arr:=[]int{}
    cnt:=map[int]int{}
    var x int
    for i:=0;i<n;i++{
        fmt.Fscan(in,&x)
        if _,ok:=cnt[x];!ok{
            cnt[x]++
            arr=append(arr,x)
        }
    }
    sort.Ints(arr)
    ans:=0
    for i,x:=range arr{
        if i>0&&x-arr[i-1]>ans{
            ans=x-arr[i-1]
        }
    }
    fmt.Print(ans)
}

发表于 2023-03-22 09:53:08 回复(0)
这题数据量小,所以直接sort就能搞定了
发表于 2022-03-19 16:19:51 回复(0)
#include<iostream>
#include<vector>
#include<algorithm>
int main()
{
    long long N,M;
    while(std::cin>>N)
    {
        std::vector<int>s;
        for(long long i=0;i<N;i++)
        {
            std::cin>>M;
            s.push_back(M);
        }
        sort(s.begin(),s.end());
        long long max=0;
        for(long long i=0;i<N-1;i++)
        {
            if(s[i+1]-s[i]>max)max=s[i+1]-s[i];
        }
        std::cout<<max<<std::endl;
    }
    return 0;
}
发表于 2020-09-17 23:27:21 回复(0)
# 简单粗暴,先把数列排序,再遍历有序数列找到最大差值,但是快速排序的时间复杂度时O(nlogn)
# 所以要使用桶排序,在Python环境中,排序方法由sorted自己决定
# 我以为会有不需要排序就能解决的方法,不知道有没有?
def max_diff(n, ln):
    nln = sorted(ln)
    l = len(nln)
    max_d = 0
    if l < 2:
        return 0
    for i in range(1, len(nln)):
        if nln[i] - nln[i-1] > max_d:
            max_d = nln[i] - nln[i-1]
    return max_d

if __name__ == "__main__":
    n = int(input())
    ln = list(map(int, input().split()))
    print(max_diff(n, ln))
发表于 2019-08-07 23:52:04 回复(0)

一、Java 桶排两个坑

提交卡翔的看过来

是不是无限卡 66.7% 测试用例啊??

搞了那么久,有两个坑

  1. 输入坑

    输入的数组长度 N 不一定是 输入的元素个数 N

  2. 爆 int 坑

    在计算桶序号的过程中,由于有乘操作,若数据范围是 20 亿左右,而 int 范围是 21 亿多点,那么计算过程中 int 就爆了,所以计算的时候必须要转换成 long 来计算

二、参考代码

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String[] args) throws IOException{
        /*
        使用这种输入 500 ms 左右
        Scanner sc = new Scanner(System.in);

        int N = Integer.parseInt(sc.nextLine());
        int[] nums = new int[N];

        String[] s = sc.nextLine().split(" ");
        for(int i = 0; i < s.length; i++){
            nums[i] = Integer.parseInt(s[i]);
        }

        sc.close();
        */
        //使用这种输入 270 ms 左右 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        String[] tmp = br.readLine().split(" ");
        br.close();
        int N = tmp.length;
        int[] nums = new int[N];

        for(int i = 0; i < N; i++){
            nums[i] = Integer.parseInt(tmp[i]);
        }

        System.out.println(solution(nums, N));

    }

    private static int solution(int[] nums, int length){
        if(nums == null || nums.length <2){
            return 0;
        }
        int len = length;
        int maxNum = Integer.MIN_VALUE;
        int minNum = Integer.MAX_VALUE;
        for(int i = 0; i < len; i++){
            maxNum = Math.max(nums[i], maxNum);
            minNum = Math.min(nums[i], minNum);
        }

        if(maxNum == minNum){
            return 0;
        }

        boolean[] hasNum = new boolean[len + 1];
        int[] bucketMaxNum = new int[len + 1];
        int[] bucketMinNum = new int[len + 1];

        for(int i = 0; i < len; i++){
            int bucketID = getBucketID(nums[i], minNum, maxNum, len);
            bucketMaxNum[bucketID] = hasNum[bucketID] ? Math.max(nums[i], bucketMaxNum[bucketID]) : nums[i];
            bucketMinNum[bucketID] = hasNum[bucketID] ? Math.min(nums[i], bucketMinNum[bucketID]) : nums[i];
            hasNum[bucketID] = true;
        }

        int res = 0;
        int lastMaxNum = bucketMaxNum[0];
        for(int i = 1; i <= len ; i++){
            if(hasNum[i]){
                res = Math.max(res, bucketMinNum[i] - lastMaxNum);
                lastMaxNum = bucketMaxNum[i];
            }
        }

        return res;
    }

    private static int getBucketID(long num, long min, long max, long len){
        return (int)((num - min)*len / (max - min));
    }
}
发表于 2019-06-30 13:56:26 回复(0)
import java.util.ArrayList;
import java.util.Scanner;
import java.util.TreeSet;
 
public class Main {
 
     
    public static void main(String[] args) {
 
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        TreeSet<Integer> set=new TreeSet<>();
        while (scanner.hasNextInt()) {
            set.add(scanner.nextInt());
        }
            
        if (set.size()==0 || set.size()==1) {
            System.out.println(0);
        }
        else {
        int max=0;
        int temp=set.pollFirst();
        while (!set.isEmpty()) {
            max=Math.max(max, set.first()-temp);
            temp=set.pollFirst();
        }
        System.out.println(max);
    }
    }
 
}
利用treeset在添加的时候自动排序的功能
发表于 2019-03-29 11:20:02 回复(0)
def main():
    N = int(input())
    num_list = list(map(int,input().split()))
    temp_list = []
    if len(num_list) < 2:
        print(0)
    else:
        num_list.sort()
        for i in range(len(num_list)-1):
            temp_list.append(num_list[i+1]-num_list[i])
        max_value = max(temp_list)
        print(max_value)



if __name__ == '__main__':
    main()

发表于 2019-03-15 09:22:19 回复(0)
#include <vector>
#include <iostream>
#include <queue>
usingnamespacestd;
intmain()
{
    intN;
    cin >> N;
    priority_queue<int, vector<int>, less<int>> pq;//最大堆
    vector<long>inputNums;
    inputNums.reserve(N);
    inputNums.resize(N);
    for(inti = 0; i < N; ++i)
    {
        cin >> inputNums[i];
        pq.push(inputNums[i]);
    }
    if(N < 2){
        cout << 0 << endl;
        return0;
    }
    intlastNums = pq.top();
    intmaxNums = 0;
    pq.pop();
    while(!pq.empty())
    {
        intnowNums = pq.top();
        pq.pop();
        if(maxNums < (lastNums - nowNums))
        {
            maxNums = (lastNums - nowNums);
        }
        lastNums = nowNums;
    }
    cout << maxNums << endl;
}

//简单的堆排序就过了,时间复杂度还是在nlogn,不知道怎么搞成n,有大佬知道的话请指点一下,谢谢

发表于 2018-09-03 18:35:47 回复(2)