声明:本文资料来自于 牛客网(算法初级笔记1)
1 小和问题
public static void main(String[] args){ int[] arr = Util.generateRandomArray(8,10); smallSum(arr); } public static void smallSum(int[] arr){ if (arr == null || arr.length < 2) { return; } System.out.println("原数组"); Util.printArray(arr); System.out.println(""); int smallSum = deal(arr,0,arr.length-1); System.out.println("处理后的数组:"); Util.printArray(arr); System.out.println("小和为:"+smallSum); } public static int deal(int[] arr,int left,int right){ if (left == right){ return 0; } int middle = left + ((right-left)>>1); return deal(arr,left,middle) + deal(arr,middle+1,right)+merge(arr,left,middle,right); } public static int merge(int[] arr,int left,int middle,int right){ int[] help = new int[right-left+1]; int sum = 0; int index = 0; int p1=left; int p2=middle+1; while (p1 <= middle && p2 <= right){ if (arr[p1] < arr[p2]){ System.out.println((right-p2+1)+"个"+arr[p1]+" \n");//打印加数 } sum += arr[p1] < arr[p2]? (right-p2+1)*arr[p1]:0; help[index++] = arr[p1] < arr[p2]? arr[p1++] : arr[p2++]; } while (p1 <= middle){ help[index++] = arr[p1++]; } while (p2 <= right){ help[index++] = arr[p2++]; } for (int i = 0;i < help.length;i++){ arr[left+i] = help[i]; } return sum; }
随机测试结果:
2 逆序对问题
在一个数组中,左边的数如果比右边的数大,则折两个数构成一个逆序对,请打印所有逆序对。
public static void main(String[] args){ int[] arr = Util.generateRandomArray(8,10); System.out.println("原始数组:"+Arrays.toString(arr)); nixudui(arr); System.out.print("处理后数组:"+Arrays.toString(arr)); } public static void nixudui(int[] arr){ deal(arr,0,arr.length-1); } public static void deal(int[] arr,int left,int right){ if (left == right){ return; } int middle = left + ((right-left)>>1); deal(arr,left,middle); deal(arr,middle+1,right); merge(arr,left,middle,right); } public static void merge(int[] arr, int left,int middle, int right){ int p1=left; int p2 = middle+1; int i = 0; int[] help = new int[right-left+1]; while (p1 <= middle && p2 <= right){ if (arr[p1] > arr[p2]){ for(int j = 0;j < middle-p1+1;j++){ System.out.println("逆序对:"+arr[p1+j]+" "+arr[p2]); } help[i++] = arr[p2++]; }else { help[i++] = arr[p1++]; } } while (p1 <= middle){ help[i++] = arr[p1++]; } while (p2 <= right){ help[i++] = arr[p2++]; } for ( i = 0;i < help.length;i++){ arr[left+i] = help[i]; } }
2个的时间复杂度为O(N * log N),空间复杂度为O(N)