第一种:纯种最短距离和

形式1:在坐标轴上有一些点,你可以在其中任意一点放置某种东西,求放置点到所有点的最小和

形式2:将所有值改成相等的某个值,每次修改可以进行加1或者减1,求最少操作数

上图源自力扣462

这种距离总和问题的统一解法,是吧这个 相等值/坐标位置 放置在中间数上。

为什么放中间数距离和最小呢?

假设四个点,放在最左侧,第一段线段计算3次,第二段计算2次,第三段计算1次

放中间的话:

则两侧计数都会减少

四个数的情况,放左右两侧效果相同,中间一段都算了两次,也就是偶数放在中间任意位置的一个可以使得距离和最小

奇数情况,放中间即可,上下两部分距离是相等的,因此也可以双指针计算差值的和

class Solution {public int minMoves2(int[] nums) {Arrays.sort(nums);int ans = 0;int n = nums.length;for(int i = 0,j=n-1; i < j; i++,j--){ans += nums[j]-nums[i];}return ans;}
}

第二种:加权最短距离和

力扣-2448

有权值的情况,我们可以按数值变化修改两侧水位线求解。

1. 假设都降到最低值,我们可以计算出一个开销 rightSum,右侧开销总和rightCostSum=XX,以及rightLen=n,左侧开销leftSum=0,以及左侧长度leftLen=0,leftCostSum=0

2. 那么此时我们往右移会发生什么呢?

左侧长度为 leftLen 个元素,每个增加了 v[i]-v[i-1],每一份的开销都会消耗 leftCostSum 的总开销(rightSum为对应方向所有cost之和),总计增加消耗 (v[i]-v[i-1])*(leftCostSum)

右侧长度为 rightLen 个元素,每个减少了 v[i]-v[i-1],每一份的开销都会减少 rightCostSum,总计减少消耗 (v[i]-v[i-1])*(rightCostSum)

3. 通过这个移动水位线的方式,我们可以计算完成所有位置的消耗

class Solution {public long minCost(int[] nums, int[] cost) {int n = nums.length;Integer[] sort = new Integer[n];for(int i = 0; i < n; i++) sort[i] = i;Arrays.sort(sort,(a,b)->nums[a]-nums[b]);int min = nums[sort[0]];int max = nums[sort[n-1]];long leftSum = 0;long rightSum = 0L;for(long c:cost) rightSum += c;long curr=0;for(int i = 0; i < n; i++){curr += ((long)nums[i]-min)*(long)cost[i];}long ans = curr;for(int i = min+1,j=0; i <= max; i++){while (j<n&&nums[sort[j]]<i){leftSum+=cost[sort[j]];rightSum-=cost[sort[j]];++j;}curr = curr-rightSum+leftSum;ans = Math.min(ans,curr);}return ans;}}

第三种:步长变换

力扣-2033

这题不一样的地方是多了一个步长,其实这个二维没有意义,当成一维去解就可以了,不同的是,步长会多了一个判断能否成功,比如步长是2,一个1一个2必然无法相等,所以这题需要增加一个同余的判断,其他与第一题相同

第四种,割补法

力扣-1684

1. 需要把1的位置转换为实际距离0点的距离,然后求得值就比较接近最小距离和了,我们先 把它当成最小距离和去求,那么完全可以采用类似第二种的处理方式,得到最小距离和

2. 偏差,左右两侧可以使用左割右补的方式,把同一位置改为相邻位置

  1. 简化问题。假设我们不限制连续K个。

    • 那么实际上,本题可看做是1的位置距离坐标轴起点的各个值,中间放置一点加油站,形成距离和的最小值问题
    • 多点求最短距离和,最佳方式是放在中位数上
    • 因此我们可以先把本题换成1距离坐标轴起点的位置,也就是索引值
  2. 限制长度K,就是长度 N 上,我们只需要其中 K 个节点的连续值。那么我们可以考虑 从 MID(MID是K/2) 到 N-MID2(MID2是K-K/2) 上面的所有值

  3. 计算次数

    • 首先图中的长条代表面积,前缀和代表当前长条和上面所有长条的距离之和
    • 有前缀和就意味着可以计算任意一行到后面某一行的面积和
    • 假设以红色条4为核心,则我们需要的面积是 红色长条*左半边长度MID(MID是K/2)-(左半边前缀和差)-等差数列。为什么要减掉个等差数列呢?因为我们计算过程中,实际上是把左边所有元素平移到4的位置。实际是对于前一个元素,只需要移动到3,再前一个只需要移动到2,逐步递减,所以就形成了一个需要减掉的等差数列
    • 对于右侧元素,我们需要的面积是 右侧前缀和-红色长条*MID2-等差数列2,如黄色部分,是需要减掉的等差数列。
    • 最终在红色长条上下的蓝色部分,即为答案
    • 枚举所有中心节点获得最优解
class Solution {public int minMoves(int[] nums, int k) {int n = nums.length;int sum = 0;for(int num:nums) sum += num;long[] arr = new long[sum];for(int i =0,j=0;i<n;i++){if(nums[i]==1) arr[j++]=i;}for(int i =1;i<arr.length;i++){arr[i] = arr[i]+arr[i-1];}long ans = Long.MAX_VALUE;int half1 = (k+1)/2;int half2 = k-half1;for(int i = half1-1; i < arr.length-half2;i++){long iPre = (i-1<0?0:arr[i-1]);long halfPre = i-half1<0?0:arr[i-half1];long leftSum = (arr[i]-iPre)*(long)(half1)-(arr[i]-halfPre);long rightSum = arr[i+half2]-iPre-(arr[i]-iPre)*(half2+1);long leftCost = leftSum-((long)(half1)*(half1-1)/2);long rightCost = rightSum-((long)(half2)*(half2+1)/2);ans = Math.min(ans,leftCost+rightCost);}return (int) ans;}}

时间复杂度:O(N+M),N为原数组长度,M为1的个数
空间复杂度:O(M)

第五种,放置K个点最短距离和

通过第一种情况,我们知道,如果确定了范围,距离一个点的最短距离和,最佳放置方式是把它放中间。那么对于K个点的情况,我们只要枚举前一个部分的分割点即可。特别地,第一个的点的放置的起始位置只能是开头。

  1. 假设一组房子拥有一个邮筒,则邮筒,应该尽可能地放在房子中间

    • 奇数放在中间
    • 偶数放在中间两个的任意一个位置
  2. 于是想到动态规划,以某点为终点,消耗几个邮筒对应的最小距离
  3. 枚举邮筒个数,以及前一个邮筒范围的结束位置,在上一个邮筒位置的基础上,把当前邮筒放在这段房子的中间,比较最小距离
class Solution {public int minDistance(int[] houses, int k) {Arrays.sort(houses);int n  =houses.length;int[][] dp = new int[n][k+1];for(int i = 0; i < n; i++){Arrays.fill(dp[i],Integer.MAX_VALUE/2);dp[i][0] = 0;}for(int i=0; i < n; i++){for(int j = 1; j <= Math.min(i+1,k); j++){for(int t = 0; t <= i;t++){dp[i][j]=Math.min((t==0?0:dp[t-1][j-1])+getDis(houses,t,i),dp[i][j]);if(j==1) break;}}}return dp[n-1][k];}private int getDis(int[] houses, int i, int j){int ans = 0;while(i<j){ans += houses[j--]-houses[i++];}return ans;}
}

时间复杂度:O(n^2*k+nlogn)
空间复杂度:O(nk)

算法总结-最短距离和问题相关推荐

  1. Floyd算法求解最短距离

    1.问题 用Floyd算法求解下图各个顶点的最短距离.写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵). 2.解析 Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权 ...

  2. 算法分析与设计实践-作业2-Dijkstra算法求最短距离

    1. 问题 对于下图使用Dijkstra算法求由顶点a到顶点h的最短路径. 2. 解析 Dijkstra算法通过从起始节点往相邻节点不断进行扫描,更新dist数组.path数组和set数组.然后遍历s ...

  3. 弗洛伊德算法(floyd)

    算法背景: 图中的A,B,C,D,E,F,G,代表7个村庄,边上的权值带表两村庄之间的距离,现在要从某一个村庄,例如G村庄,往另外几个村庄送邮件,问任意一村庄到其他各村庄的最短距离分别是多少? 思路: ...

  4. 迪杰斯特拉(dijkstra)-两个地铁站最短距离

    文章目录 前言 Github 算法原理 类职责划分 Code Station&Result&DataBuilder 算法 应用场景 总结 作者 前言 最新更新了github.欢迎多评论 ...

  5. K近邻算法学习(KNN)

    K近邻算法--KNN 机器学习--K近邻算法(KNN) 基本知识点 基本原理 示例 关于KNN的基本问题 距离如何计算? k如何定义大小? k为为什么不定义一个偶数? KNN的优缺点 代码实现 第一次 ...

  6. 【优化布局】基于免疫算法求解充电站最优布局matlab代码

    1 简介 为了普及电动汽车,以缓解我国日益严重的环境能源问题,本文研究电动汽车充换电站的选址方法,旨在利用提高电动汽车充电设施的覆盖范围,加快电动汽车的普及发展.本文建立人们日常出行模型,模拟电动汽车 ...

  7. 我的第一本算法书--读书笔记

    序–算法的基本知识 1.什么是算法 计算或解决问题的步骤. 算法和程序的区别 程序是以计算机能够理解的编程语言编写的,算法是以人能够理解的方式描述. 排序 排列整数的算法 选择排序 查找最小的数字并交 ...

  8. 简单成都地铁信息查询系统,BFS算法实现最短路径查找

    前言 最近数据结构期末作业要求做一个成都地铁信息系统,在网上查阅了相关资料之后,做了出来,因为复用性极强,且代码注释都比较详细,于是决定分享出来 思路 总的来说就是从两个文本文件中读入站点和站点信息, ...

  9. 传统的线性降维方法效果不佳。_机器学习西瓜书简明笔记(11)降维与度量学习...

    上篇主要介绍了几种常用的聚类算法,首先从距离度量与性能评估出发,列举了常见的距离计算公式与聚类评价指标,接着分别讨论了K-Means.LVQ.高斯混合聚类.密度聚类以及层次聚类算法.K-Means与L ...

最新文章

  1. [NOIP1999] 提高组 洛谷P1014 Cantor表
  2. python中mainloop添加背景_Python实例讲解 - tkinter canvas (设置背景图片及文字)
  3. UI自动化之读取浏览器配置
  4. SQL中and和or的区别是?
  5. 【Linux系列】centos7中防火墙相关命令
  6. Keepalived实现高可用Nginx反向代理
  7. java synoch 加锁_线程间通信 - HappyCowboy - 博客园
  8. 【java学习之路】(javaWeb【后端】篇)007.AjaxAxios
  9. Redis教程:数据库
  10. 局域网入侵教程_黑客常用Linux 入侵工具:可获取目标浏览图片的EtterCap
  11. 服务器XP系统打印机共享设置,小编调解xp系统打印机共享设置和使用的详细教程...
  12. 小学计算机应用到英语课教案,信息技术助力小学英语课堂教学妙招
  13. 漫谈Anchor-based和Anchor-Free
  14. mysql数据库如何查看表空间_MYSQL:查看的数据库表空间
  15. 二甲苯酚的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  16. 关于安全域的划分与风险管理
  17. Illegal string offset错误
  18. 智能驾驶中预期安全系统的架构
  19. 英文构词法 —— circum- 前缀
  20. 计算机附件计算器的用法,计算机附件中计算器使用方法.doc

热门文章

  1. 停止服务、重新启动和重新加载服务
  2. 深度增强学习(DRL)漫谈 - 从DQN到AlphaGo
  3. Python: 房天下小区数据爬取
  4. 双路由设置上网与共享
  5. 基于NXP i.MX 8M Mini芯片的MYC-C8MMX核心板详细资料
  6. win10系统添加网络打印机过程
  7. 工资管理系统设计与实现
  8. 双线路带宽叠加后,指定网站走指定线路!
  9. 期望值、方差、协方差、相关系数,numpy 计算均值、方差、协方差,相关系数
  10. 那些年 回不去的时光深处