泡泡的课堂小练习之远亲不如近邻

题目描述

小明最近搬到了一座新的城镇,这个城镇可以看成是一个一维的坐标系。城镇上有n个居民,第i个居民的位置为ai。现在牛牛有m个搬家方案,在第i个方案中他会搬到位置xi。

俗话说的好,远亲不如近邻。现在小明想知道,对于每个搬家方案,搬家后与最近的居民的距离为多少。

  • 输入
  • 3,2,[2,4,7],[5,8]
  • 返回值 [1,1]
  • 说明
  • 第一个方案搬到位置5,与5最近的居民在位置4,距离为1.
  • 第二个方案搬到位置8,与8最近的居民在位置7,距离为1

暴力破解

/**
     * 远亲不如近邻
     * @param n int整型 居民个数
     * @param m int整型 方案个数
     * @param a int整型vector 居民的位置
     * @param x int整型vector 方案对应的位置
     * @return int整型vector
     */
    vector<int> solve(int n, int m, vector<int>& a, vector<int>& x) 
    {
    	//对居民位置进行排序
        sort(a.begin(), a.end());
        vector<int> v1;//记录距离
        //遍历装修计划
        for(int i=0;i<x.size();i++)
        {
        	//记录最小值
            int m=0;
            //情况1:当搬家地点比第一个居民的地点还要小的时候
            if(x[i]<=a[0])
            {
                m=a[0]-x[i];
            }
            //情况2:当搬家的地点比最后一个居民的地点还要大的时候
            else if(x[i] >= a[a.size()-1])
            {
                m=x[i]-a[a.size()-1];
            }
            //情况3:当搬家地点在居民区间时
            else
            {
            	//遍历居民的地点容器找出前一个比该值小,后一个比该值大的地方
                for(int j=1;j<a.size();j++)
                {
                    if(x[i] <= a[j])
                    {
                    	//计算比较与前一个居民的地点的距离和后一个居民的地点的距离,取其中较小值,然后退出
                        m=(x[i]-a[j-1])<(a[j]-x[i])?(x[i]-a[j-1]):(a[j]-x[i]);
                        break;
                    }
                }
            }
            v1.push_back(m);
        }
        return v1;
    }

在这里插入图片描述

二分法

  • 使用上面那种方法时,每有一种搬家计划时,就要遍历一遍a容器,大大增加的运行时间
  • 那么使用二分法的话,通过对半分的原则,可以在一定程度上缩减检索的时间
		vector<int> solve(int n, int m, vector<int>& a, vector<int>& x) 
		{
        sort(a.begin(), a.end());
        vector<int> v1;//记录距离
        for(int i=0;i<m;i++)
        {
        		//给v一个最大值,保证在第一次比较时不会被初始值影响
                int v=INT_MAX;
                //记录左下标
                int left=0;
                //记录右下标
                int right=n-1;
                //循环-直到左坐标大于右坐标
                while(left<=right)
                {
                	//中间值
                    int mid=left+(right-left)/2;
                    //记录当前近邻的距离,然后取两者间较小的值
                    if(abs(a[mid]-x[i]) < v)
                    {
                        v=abs(a[mid]-x[i]);
                    }
                    //如果中间值比搬家计划的地点小,从右半部分继续分
                    if(a[mid]<x[i])
                    {
                        left=mid+1;
                    }
                    //如果中间值比搬家计划地点大,从左半部分继续分
                    else if(a[mid] > x[i])
                    {
                        right=mid-1;
                    }
                    //如果中间值刚好等于搬家计划地点,那么差距就为0,因为不存在比0更小的,所以直接退出当前循环即可
                    else
                    {
                        v=0;
                        break;
                    }
                }
            v1.push_back(v);
        }
        return v1;
    }

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值