• 邻值查找—算法进阶指南


    邻值查找

    给定一个长度为 n 的序列 A,A 中的数各不相同。对于 A 中的每一个数 Ai,求: min1≤j<i|Ai−Aj|

    以及令上式取到最小值的 j(记为 Pi)。若最小值点不唯一,则选择使 Aj 较小的那个。

    输入格式
    第一行输入整数n,代表序列长度。
    第二行输入n个整数A1…An,代表序列的具体数值,数值之间用空格隔开。

    输出格式
    输出共n-1行,每行输出两个整数,数值之间用空格隔开。
    分别表示当i取2~n时,对应的min1≤j<i|Ai−Aj|和Pi的值。

    数据范围
    n≤105,|Ai|≤109
    输入样例:
    3
    1 5 3
    输出样例:
    4 1
    2 1


    这里提供一个双向链表的写法


    EXAMPLE IN PUT
    10
    4 5 6 1 2 3 7 8 9 10

    OUTPUT
    1 1
    1 2
    3 1
    1 4
    1 5
    1 3
    1 7
    1 8
    1 9

    具体思路如下图
    Befor

    value 4 5 6 1 2 3 7 8 9 10
    id 1 2 3 4 5 6 7 8 9 10

    我们先标记初始值的id

    Sorted 我们在前后设置了两个哨兵。

    value 1 2 3 4 5 6 7 8 9 10
    id 0 4 5 6 1 2 3 7 8 9 10 11

    然后从后面枚举

    value 1 2 3 4 5 6 7 8 9 10
    id 0 4 5 6 1 2 3 7 8 9 10 11

    得到
    相邻最小可选的 id——9 11
    ———————value—1 ∞
    我们选出最佳的 id 是 9 .
    如图,我们删去这个元素,把这个删去元素的前后相连。
    不断重复如上操作,最后到只剩一个元素。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    const int N = 1e5 + 10;
    int p[N], l[N], r[N], n;
    pair<int, int> a[N], ans[N];
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i].first);
            a[i].second = i;
        }
        a[0].first = 1e9;
        a[n + 1].first = -1e9;
        sort(a + 1, a + n + 1);
        for(int i = 1; i <= n; i++) {
            p[a[i].second] = i;
            l[i] = i - 1;
            r[i] = i + 1;
        }
        for(int i = n; i >= 2; i--) {
            int pos = p[i];
            int Left = l[pos];
            int Right = r[pos];
            int vl = abs(a[pos].first - a[Left].first);
            int vr = abs(a[pos].first - a[Right].first);
            if(vl <= vr) {
                ans[i].first = vl;
                ans[i].second = a[Left].second;
            }
            else {
                ans[i].first = vr;
                ans[i].second = a[Right].second;
            }
            r[Left] = Right;
            l[Right] = Left; 
        }
        for(int i = 2; i <= n; i++)
            printf("%d %d
    ", ans[i].first, ans[i].second);
        return 0;
    }
    
  • 相关阅读:
    Android&Java面试题大全—金九银十面试必备
    android招聘啦,美图秀秀欢迎你加入!
    android经典源码,很不错的开源框架
    MongoDB、Hbase、Redis等NoSQL优劣势、应用场景
    体验go语言的风骚式编程
    金九银十中,看看这31道Android面试题
    android高级页面效果集锦
    flask中的request
    flask笔记(三)Flask 添加登陆验证装饰器报错,及解析
    flask笔记(二)
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12601185.html
Copyright © 2020-2023  润新知