求一个数组中a[0...i-1] 离a[i]最接近的值

博客主页:http://blog.csdn.net/minna_d

题目:

给一个n个元素的线性表A,对于每个数Ai,找到它之前的数中,和它最接近的数。即对于每个i,计算

Ci = min{|Ai-Aj| | 1<=j<i} 规定C1 = 0。


其实就是给定一个数组, 在a[0....i-1]中求离a[i]最近的值, 其实这里有个bug,那就是,如果对与6而言5,7都离它一样, 那么该输出谁呢

N久不写C, 感觉怪怪的, 写了一个java版。

思路:

用一个临时数组存储,离a[i]最近值

用另外一个数组存储前a[0, i-1]的排序

这样一个好处就就是能在result[i-1]的基础之上计算result[i]的结果,

查询时间复杂度为lgn,插入时间复杂度为1(因为Arrays.copy中调用System.arraycopy的缘故)

public static void main(String[] args) {

        List<Integer> list = Lists.newArrayList(1, 8, 6, 6, 7, 5, 4, 1, 0, 8);
        Integer[] result = new Integer[list.size()];
        List<Integer> tmp = Lists.newArrayList(list.get(0));
        result[0] = 0;
        for (int i = 1; i < list.size(); i++) {

            Integer willBeSort = list.get(i);
            Integer shouldInsert = Collections.binarySearch(tmp, willBeSort);

            // 该值已经存在
            if (shouldInsert >= 0) {
                result[i] = willBeSort;
                tmp.add(shouldInsert, willBeSort);
                continue;
            }

            shouldInsert = Math.abs(shouldInsert + 1);

            // 在最后位置插入
            if (shouldInsert == tmp.size()) {
                result[i] = list.get(shouldInsert - 1);
                tmp.add(shouldInsert, willBeSort);
                continue;
            }

            // 在最前位置插入
            if (shouldInsert == 0) {
                result[i] = list.get(0);
                tmp.add(shouldInsert, willBeSort);
                continue;
            }

            // 中间位置插入
            int b = tmp.get(shouldInsert);
            int a = tmp.get(shouldInsert - 1);
            result[i] = Math.abs(a - willBeSort) > Math.abs(b - willBeSort) ? b : a;
            tmp.add(shouldInsert, willBeSort);
        }

        System.out.println(Joiner.on(",").join(result));
    }

输出结果:

0,1,8,6,6,6,5,1,1,8







 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值