求一个数组中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) {
                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;
            }

            if (willBeSort.equals(tmp.get(shouldInsert))) {
                result[i] = willBeSort;
                tmp.add(shouldInsert, willBeSort);
                continue;

            }

            int b = tmp.get(shouldInsert);
            int a = tmp.get(shouldInsert - 1);

            if (willBeSort.equals(a)) {
                result[i] = a;
                tmp.add(shouldInsert, willBeSort);
                continue;
            }

            if (willBeSort.equals(b)) {
                result[i] = b;
                tmp.add(shouldInsert, willBeSort);
                continue;

            }

            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

时间: 2024-10-06 16:35:47

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

巧妙利用快速排序法的原理求一个数组中的第10大元素

//快速排序法 int QuickSort_process3(int *a, int low, int high) { int l, h, temp; l = low; h = high; temp = a[low]; while (l < h){ while (l< h&&a[h] >= temp) --h; if (l < h) a[l] = a[h]; while (l < h&&a[l] < temp) ++l; if (l &l

软件工程结对开发之求一个数组中连续最大子数组之和

一.团队成员: 檀威,陈志利 二.项目名: 求一个数组中连续最大子数组之和 三.我们的设计思路: 设sum[i]为以第i个元素结尾且和最大的连续子数组.对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且它们之和最大的连续子数组要么是以第i-1个元素结尾且它们之和最大的连续子数组加上这个元素,要么是只包含第i个元素,即sum[i] = max(sum[i-1] + arr[i], arr[i]).可以通过判断sum[i-1] + arr[i]是否大于arr[i]来做

求一个数组中只出现一次的数字

/* 求一个数组中只出现一次的数字(注:只针对数组中有两个数不同,且其他数字两两相同) 题目:一个整型数组里除了两个数字出现一次外,其他的数字都出现了两次:求出现一次的数字: 如:数组a[]={2,4,3,6,3,2,5,5};执行程序后应输出4和6:因为4,6只在该数组中出现了一次 思路:两个数字相同其异或结果一定为0,先异或->再分组-->再对每个子序列异或 算法: 1. 先对数组的每一个元素进行异或操作,求结果(本质就是对那两个不同的数的异或,即4^6=0010) 2.根据异或的操作结果

求一个数组中最大连续子序列的和

10.求一个数组中最大连续子序列的和 参考链接:http://blog.csdn.net/butwang/article/details/4691974 思路:如果已经知道在前0~k-1共k个元素中,在最大和为MaxAll[k-1], 怎么求0~k共k+1个元素的MaxAll[k]. 如果前k个元素的最大和子序列包括a[k-1],则很容易知道MaxAll[k] = max(MaxAll[k-1] + a[k], a[k]).那如果前k个元素的最大和子序列不包括a[k-1]呢?在数组后面增加一个元

“支配着” 是在数组中出现频率超过一半的整数,求一个数组中的支配者

"支配着" 是在数组中出现频率超过一半的整数,例如{3, 2, 3, 3, 0, 2, 3, 4, 3},其中3出现5次,5除以9大于0.5,所以3是支配者.写一个函数,在给定的整数数组中找出支配者是多少,如果一个数组中没有支配者,则返回1. package cn.usst.DataTest5; import java.util.Arrays; public class DataTest5 { /** * "支配着" 是在数组中出现频率超过一半的整数 * @para

[LeetCode169]Majority Element求一个数组中出现次数大于n/2的数

题目: Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority element always exist in the array. 思路:可以利用Dictionary将数组中每个数

求一个数组中最小的K个数

方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如果大于最大元素则忽略,如果小于最大元素则将次元素送入堆中,并将堆的最大元素删除,调整堆的结构; 方法3:使用复杂度为O(n)的快速选择算法..................... /** * Created by elvalad on 2014/12/8. * 输入N个整数,输出最小的K个 */ impor

求一个数组中只有一个和两个数字出现了一次,其余成对出现

//一个数字出现一次 #include<iostream> using namespace std; int once(int* a, int num) {  int ret = 0;  for (int i = 0; i < num; ++i)  {   ret ^= a[i];  }  return ret; } int main() {  int array[5] = { 1, 2, 2, 3, 3 };  int sum = once(array, 5);  cout <&

分治法求一个数组中最大最小值

分治法:将一个复杂的一分为二,然后对这两部分递归调用该函数,直到找到函数出口,求解出最简单的情况 需要注意的是分治时开始和结束位置参数的选择,一开始写的是s到mid-1,另一个是mid到e,然后就会数组为奇数个时结果对,为偶数个时结果错,后面改为s到mid,另一个是mid+1到e 结果就对了. #include<iostream> using namespace std; #define N 10 #define MAX(a,b)(a>b?a:b) #define MIN(a,b)(a&