当前位置:   article > 正文

小和问题与逆序对问题_小和问题和逆序对问题

小和问题和逆序对问题

一、小和问题

在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。

(1)遍历左边 O(N^2)

(2)归并 O(N)

例子:求[1, 3, 4, 2, 5]的小和

1+(1+3)+1+(1+3+4+2)= 16

代码实现:

  1. public static int smallSum(int[] arr) {
  2. if (arr == null || arr.length < 2) {
  3. return 0;
  4. }
  5. return mergeSort(arr, 0, arr.length - 1);
  6. }
  7. public static int mergeSort(int[] arr, int l, int r) {
  8. if (l == r) {
  9. return 0;
  10. }
  11. int mid = l + ((r - l) >> 1);
  12. return mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r) + merge(arr, l, mid, r);
  13. }
  14. public static int merge(int[] arr, int l, int m, int r) {
  15. int[] help = new int[r - l + 1];
  16. int i = 0;
  17. int p1 = l;
  18. int p2 = m + 1;
  19. int res = 0;
  20. while (p1 <= m && p2 <= r) {
  21. res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
  22. help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
  23. }
  24. while (p1 <= m) {
  25. help[i++] = arr[p1++];
  26. }
  27. while (p2 <= r) {
  28. help[i++] = arr[p2++];
  29. }
  30. for (i = 0; i < help.length; i++) {
  31. arr[l + i] = help[i];
  32. }
  33. return res;
  34. }
  35. // for test
  36. public static int comparator(int[] arr) {
  37. if (arr == null || arr.length < 2) {
  38. return 0;
  39. }
  40. int res = 0;
  41. for (int i = 1; i < arr.length; i++) {
  42. for (int j = 0; j < i; j++) {
  43. res += arr[j] < arr[i] ? arr[j] : 0;
  44. }
  45. }
  46. return res;
  47. }
  48. // for test
  49. public static int[] generateRandomArray(int maxSize, int maxValue) {
  50. int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
  51. for (int i = 0; i < arr.length; i++) {
  52. arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
  53. }
  54. return arr;
  55. }
  56. // for test
  57. public static int[] copyArray(int[] arr) {
  58. if (arr == null) {
  59. return null;
  60. }
  61. int[] res = new int[arr.length];
  62. for (int i = 0; i < arr.length; i++) {
  63. res[i] = arr[i];
  64. }
  65. return res;
  66. }
  67. // for test
  68. public static boolean isEqual(int[] arr1, int[] arr2) {
  69. if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
  70. return false;
  71. }
  72. if (arr1 == null && arr2 == null) {
  73. return true;
  74. }
  75. if (arr1.length != arr2.length) {
  76. return false;
  77. }
  78. for (int i = 0; i < arr1.length; i++) {
  79. if (arr1[i] != arr2[i]) {
  80. return false;
  81. }
  82. }
  83. return true;
  84. }
  85. // for test
  86. public static void printArray(int[] arr) {
  87. if (arr == null) {
  88. return;
  89. }
  90. for (int i = 0; i < arr.length; i++) {
  91. System.out.print(arr[i] + " ");
  92. }
  93. System.out.println();
  94. }

 

二、逆序对问题

在一个数组中,左边的数如果比右边的数大,则这两个数构成一个逆序对。跟小和问题实际上是一样的。

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/227505
推荐阅读
相关标签
  

闽ICP备14008679号