BM20 数组中的逆序对
链接:https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
本题采用归并排序的思想对问题进行求解,即在每次递归归并中,对递归出的子问题考虑能组成逆序对的个数,来以此累加。
解题代码:
1 static int mod = (int) (1e9 + 7); 2 //逆序对问题 3 public int InversePairs(int [] array) { 4 if (array == null ||array.length == 1 ) { 5 return 0; 6 } 7 return process(array,0,array.length - 1) % mod; 8 } 9 10 public int process(int[] array,int l,int r) { 11 if (l == r) { 12 return 0; 13 } 14 int mid = l + ((r - l) >> 1); 15 return (process(array,l,mid) + process(array,mid + 1,r) + merge(array,l,mid,r)) % mod; 16 } 17 18 public int merge(int[] array,int l,int mid,int r) { 19 int ans = 0; 20 int i = l, j = mid + 1; 21 int[] help = new int[r - l + 1]; 22 int cnt = 0; 23 while (i <= mid && j <= r) { 24 if (array[i] > array[j]) { 25 ans += r - j + 1; 26 help[cnt++] = array[i++]; 27 } 28 else { 29 help[cnt++] = array[j++]; 30 } 31 } 32 while (i <= mid) { 33 help[cnt++] = array[i++]; 34 } 35 while (j <= r) { 36 help[cnt++] = array[j++]; 37 } 38 for (int k = 0; k < r - l + 1; k++) {//此处是help数组的长度,而不是array数组的长度 39 array[k + l] = help[k]; 40 } 41 return ans % mod; 42 }
还可以借鉴这道题的思路:
1 /*利用归并排序思想,求解部分最小和的问题 2 * 如arr = {1,3,4,2,5} ,则对于1来说左侧没有比1小的数,所以和为0 3 * 对于3来说左侧有个1比3小,所以和为1 4 * 对于4来说左侧有个1和3比4小,所以和为4 5 * 对于2来说左侧有个1比2小,所以和为1 6 * 对于5来说左侧有1,3,4,2比5小,所以和为10 所以总和为16 7 */ 8 /* 9 * 可以换一种思路进行求解: 10 * 1.对于第一个1,之后有3,4,2,5四个数都比它大,所以共要加4次 11 * 2.对于第二个3,之后有4,5两个数都比它大,所以共要加2次 12 * 3.按照这个思路以此类推至最后一个元素 13 * 14 * 所以可以沿用归并排序的思想,每次归并时,如果左边的数比右边的数小,则加上一次左边的这个数 15 */ 16 17 public static int MergeAll(int[] arr) 18 { 19 if (arr == null || arr.length == 1) { 20 return 0; 21 } 22 return process(arr,0,arr.length - 1); 23 } 24 25 public static int process(int[] arr,int l,int r) 26 { 27 if (l == r) { 28 return 0; 29 } 30 int mid = l + ((r - l) >> 1); 31 32 return process(arr,l,mid) + process(arr,mid + 1,r) + Merge(arr,l,mid,r); 33 } 34 35 public static int Merge(int[] arr,int l,int mid,int r) 36 { 37 int ans = 0; 38 int i = l, j = mid + 1; 39 int[] help = new int[r - l + 1]; 40 int cnt = 0; 41 while (i <= mid && j <= r) { 42 if (arr[i] < arr[j]) { 43 ans += arr[i] * (r - j + 1); 44 help[cnt++] = arr[i++]; 45 } 46 else { 47 help[cnt++] = arr[j++]; 48 } 49 } 50 while (i <= mid) { 51 help[cnt++] = arr[i++]; 52 } 53 while (j <= r) { 54 help[cnt++] = arr[j++]; 55 } 56 for (int k = 0; k < r - l + 1; k++) { 57 arr[k + l] = help[k]; 58 } 59 return ans; 60 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧