在这篇博客中,我们将深入探讨如何使用Java解决一个有趣的问题:求解数组的小和问题。我们将首先理解问题的定义,然后逐步分析和解释给出的Java代码。
问题定义
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。例如,数组[1,3,4,2,5]的小和为1+1+3+1+1+3+2=12。
代码解析
首先,我们定义了一个类 Code02_SmallSum
,该类包含了一系列的方法,用于求解数组的小和。以下是我们将要讨论的主要方法:
smallSum方法
public static int smallSum(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
return process(arr, 0, arr.length - 1);
}
smallSum
方法是我们的主要方法,它接收一个整数数组作为输入,如果数组为空或者长度小于2,那么直接返回0,否则调用 process
方法进行处理。
process方法
public static int process(int[] arr, int l, int r) {
if (l == r) {
return 0;
}
// l < r
int mid = l + ((r - l) >> 1);
return
process(arr, l, mid)
+
process(arr, mid + 1, r)
+
merge(arr, l, mid, r);
}
process
方法是一个递归方法,它接收一个整数数组和两个索引 l
和 r
作为输入,表示要处理的数组范围。首先,如果 l
等于 r
,那么直接返回0。然后,计算中间索引 mid
,并递归地处理左半部分和右半部分,最后将两个部分合并。
merge方法
public static int merge(int[] arr, int L, int m, int r) {
int[] help = new int[r - L + 1];
int i = 0;
int p1 = L;
int p2 = m + 1;
int res = 0;
while (p1 <= m && p2 <= r) {
res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
return res;
}
merge
方法是用于合并两个部分的,它接收一个整数数组和三个索引 L
、 m
和 r
作为输入,表示要合并的数组范围和中间索引。这个方法的主要思想是使用两个指针 p1
和 p2
,分别指向左半部分的开始和右半部分的开始。然后,比较两个指针指向的元素,如果 p1
指向的元素小于 p2
指向的元素,那么将 p1
指向的元素加入到结果中,并向右移动 p1
,否则将 p2
指向的元素加入到结果中,并向右移动 p2
。这个过程一直持续到 p1
或 p2
到达各自的部分的末尾。
测试代码
// for test
public static int comparator(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
int res = 0;
for (int i = 1; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
res += arr[j] < arr[i] ? arr[j] : 0;
}
}
return res;
}
// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
int[] arr2 = copyArray(arr1);
if (smallSum(arr1) != comparator(arr2)) {
succeed = false;
printArray(arr1);
printArray(arr2);
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
}
在 main
方法中,我们生成了一些随机数组,并使用 smallSum
方法和一个简单的比较方法 comparator
进行了测试,以验证我们的解决方案是否正确。文章来源:https://www.toymoban.com/news/detail-566004.html
总结
以上就是我们对求解数组的小和问题的Java代码的解析。希望这篇博客能够帮助你理解和掌握这个问题的解决方案。如果你有任何问题或者建议,欢迎在下面的评论区留言。文章来源地址https://www.toymoban.com/news/detail-566004.html
到了这里,关于Java代码解析:求解数组的小和问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!